Kaopiz / KProgressHUD

An implement of ProgressHUD for Android, similar to MBProgressHUD, SVProgressHUD for iOS.
Apache License 2.0
1.65k stars 382 forks source link

crash at showing progress dialog #48

Open AhmadullahSaikat opened 6 years ago

AhmadullahSaikat commented 6 years ago

android.view.WindowLeaked: Activity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView{360ddfca V.ED.... R......D 0,0-108,108} that was originally added here

code:

            hud = KProgressHUD.create(this)
                    .setStyle(KProgressHUD.Style.SPIN_INDETERMINATE)
                    .setCancellable(false)
                    .setAnimationSpeed(2)
                    .setDimAmount(0.5f)
                    .show();
michzio commented 6 years ago

Yes I have the same issue it happens when there is Screen rotation. I have spinning progress then rotate, and in the same time there should be success KProgressHUD ... .show()

michzio commented 6 years ago

Maybe here:

public KProgressHUD show() { if (!isShowing()) { mFinished = false; if (mGraceTimeMs == 0) { mProgressDialog.show(); } else { mGraceTimer = new Handler(); mGraceTimer.postDelayed(new Runnable() { @Override public void run() { if (mProgressDialog != null && !mFinished) { mProgressDialog.show(); } } }, mGraceTimeMs); } } return this; }

Should be something like this

val activity = (context as? Activity) if(activity != null && activity.window.decorView.isShown) { //Show Your KProgressHUD

}

I tested outside as wrapper of hud.show() and it sometimes helps but not always as sometimes activity.window.decorView.isShown return true and as before detaching.

michzio commented 6 years ago

I have modified KProgressHUD like this

public class KProgressHUD implements LifecycleObserver {

    private static final String TAG = "KProgressHUD";

    public enum Style {
        SPIN_INDETERMINATE, PIE_DETERMINATE, ANNULAR_DETERMINATE, BAR_DETERMINATE
    }

    // To avoid redundant APIs, make the HUD as a wrapper class around a Dialog
    private ProgressDialog mProgressDialog;
    private float mDimAmount;
    private int mWindowColor;
    private float mCornerRadius;
    private Context mContext;

    private int mAnimateSpeed;

    private int mMaxProgress;
    private boolean mIsAutoDismiss;

    private int mGraceTimeMs;
    private Handler mGraceTimer;
    private boolean mFinished;

    private Lifecycle mLifecycle;
    private boolean canShowProgressDialog = false;

    private Handler mMainUiHandler;

    public KProgressHUD(LifecycleOwner lifecycleOwner, Context context) {

        lifecycleOwner.getLifecycle().addObserver(this);
        mLifecycle = lifecycleOwner.getLifecycle();

        mContext = context;
        mMainUiHandler = new Handler(context.getMainLooper());
        mProgressDialog = new ProgressDialog(context);
        mDimAmount = 0;
        //noinspection deprecation
        mWindowColor = context.getResources().getColor(R.color.kprogresshud_default_color);
        mAnimateSpeed = 1;
        mCornerRadius = 10;
        mIsAutoDismiss = true;
        mGraceTimeMs = 0;
        mFinished = false;

        setStyle(Style.SPIN_INDETERMINATE);
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    void onResume() {
        canShowProgressDialog = true;
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    void onPause() {
        canShowProgressDialog = false;
        if(mProgressDialog != null && mProgressDialog.isShowing()) {
            mProgressDialog.dismiss();
        }
    }

and show() method

public KProgressHUD show() {
        if (!isShowing()) {
            mFinished = false;
            if (mGraceTimeMs == 0) {
                if(canShowProgressDialog) {
                    mMainUiHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            mProgressDialog.show();
                        }
                    });
                }
            } else {
                mGraceTimer = new Handler();
                mGraceTimer.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        if (mProgressDialog != null && !mFinished) {
                            if(canShowProgressDialog) {
                                mMainUiHandler.post(new Runnable() {
                                    @Override
                                    public void run() {
                                        mProgressDialog.show();
                                    }
                                });
                            }
                        }
                    }
                }, mGraceTimeMs);
            }
        }
        return this;
    }

now it seems to fix my issue while rotating screen and calling show(), and also non-UI thread issues. But I need to call hud.show() after some delay ex. 500ms to correctly detect that Activity is destroying.

If you have any ideas please write them here.

zhangchaoxu commented 6 years ago

I encountered the same issue

mikilangkilo commented 5 years ago

try { progressHUD.show(); }catch (Exception e){ CrashReport.postCatchedException(BuglyException.getInstance("kprogresshub error", e)); }

i have no idea why huawei mobile always crash at show(), i have no way but to add this. please help