M.A.Murali
M.A.Murali

Reputation: 10158

Android leaked window in fragment

I know it is a duplicate question but I could not solve my problem the same in the fragments. in first fragment I have a AsyncTask with ProgressDialog and its redirect to second fragment, In second fragment I press device back button I get leaked window exception in first fragment.

I have spent more time but I could not get solution. how to get solved this issue? please help me.

This is my first (MyAccount_MySpot) fragment code:

public class MyAccount_MySpot extends Fragment {

    private ProgressDialog dialog;

    private View v;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {

        v = inflater.inflate(R.layout.setting_myacc_myspot_listview,
                container, false);

        new GetAllCreatedSPOT().execute();

        addressList.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> arg0, View arg1,
                    int position, long arg3) {
                // move to second fragment
            }
        });

        if (container == null) {
            return null;
        }

        return v;
    }



    class GetAllCreatedSPOT extends AsyncTask<Void, String, String>{
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            dialog = new ProgressDialog(getActivity());
            dialog.setMessage("please wait");
            dialog.setCancelable(false);
            dialog.show(); // I get leaked window error here when back from second fragment

        }

        @Override
        protected String doInBackground(Void... params) {
            .................
            return response;
        }

        @Override
        protected void onPostExecute(String result) {
            super.onPostExecute(result);
            ..............
            dialog.dismiss();
        }

    }

}

Full log code:

 Activity com.fssd.spot.MainActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@41cff538 that was originally added here
 android.view.WindowLeaked: Activity com.fssd.spot.MainActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@41cff538 that was originally added here
    at android.view.ViewRootImpl.<init>(ViewRootImpl.java:378)
    at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:292)
    at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:224)
    at android.view.WindowManagerImpl$CompatModeWrapper.addView(WindowManagerImpl.java:149)
    at android.view.Window$LocalWindowManager.addView(Window.java:547)
    at android.app.Dialog.show(Dialog.java:285)
    at com.fssd.spot.setting.MyAccount_MySpot$GetAllCreatedSPOT.onPreExecute(MyAccount_MySpot.java:140)
    at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:586)
    at android.os.AsyncTask.execute(AsyncTask.java:534)
    at com.fssd.spot.setting.MyAccount_MySpot.onCreateView(MyAccount_MySpot.java:65)
    at android.support.v4.app.Fragment.performCreateView(Fragment.java:1478)
    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:927)
    at android.support.v4.app.FragmentManagerImpl.attachFragment(FragmentManager.java:1280)
    at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:672)
    at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1460)
    at android.support.v4.app.Fragment.performStart(Fragment.java:1499)
    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:957)
    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1104)
    at android.support.v4.app.BackStackRecord.popFromBackStack(BackStackRecord.java:764)
    at android.support.v4.app.FragmentManagerImpl.popBackStackState(FragmentManager.java:1509)
    at android.support.v4.app.FragmentManagerImpl.popBackStackImmediate(FragmentManager.java:488)
    at android.support.v4.app.FragmentActivity.onBackPressed(FragmentActivity.java:179)
    at com.fssd.spot.MainActivity.onBackPressed(MainActivity.java:307)
    at android.app.Activity.onKeyUp(Activity.java:2131)
    at android.view.KeyEvent.dispatch(KeyEvent.java:2644)
    at android.app.Activity.dispatchKeyEvent(Activity.java:2361)
    at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1825)
    at android.view.ViewRootImpl.deliverKeyEventPostIme(ViewRootImpl.java:3585)
    at android.view.ViewRootImpl.handleImeFinishedEvent(ViewRootImpl.java:3555)
    at android.view.ViewRootImpl$ViewRootHandler.handleMessage(ViewRootImpl.java:2805)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:213)
    at android.app.ActivityThread.main(ActivityThread.java:4787)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:511)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:556)
    at dalvik.system.NativeStart.main(Native Method)

Upvotes: 0

Views: 2872

Answers (3)

Joe Plante
Joe Plante

Reputation: 6368

If you are using an AsyncTask, you'll have to do a bit of Activity/Fragment lifecycle management. AsyncTasks is reported to be one of the top causes of Android crashes. The cause is usually trying to do something UI-related once the Activity offed itself while the AsyncTask is still running

There's several ways to do it. There's Activity.isFinishing() and Activity.isDestoryed(), which may or may not work for you, in some cases because it requires a certain Android version. Another way is to keep a variable like

boolean mShowStuffInAsyncTask = false;

Set that to true onStart() or onResume() and false on onStop() or onPause(). Of course, pair onStart() with onStop() and onPause() with onResume(). This variable will tell you if it's safe to do stuff on the UI thread

Upvotes: 0

Siddharth_Vyas
Siddharth_Vyas

Reputation: 10100

Use

dialog = new ProgressDialog(getApplicationContext());

instead of

dialog = new ProgressDialog(getActivity());

Upvotes: 1

Justin Breitfeller
Justin Breitfeller

Reputation: 13801

You are heading down a road that won't ever produce a workable solution. AsyncTasks are often alive (in memory) longer than the life cycle of your activity and dialog. It sounds like the activity containing the dialog created by your AsyncTask is dying and, as such, reporting that the dialog-owned window was never dismissed.

If you do some searching on Google, there are various solutions to showing progress dialogs in conjunction with AsyncTasks. One relatively simple way you could achieve your goal is to have your async task run inside a retained DialogFragment that shows a progress dialog.

Upvotes: 0

Related Questions