Android在片段中泄露了窗口

时间:2013-10-18 18:07:33

标签: android android-fragments android-memory

我知道这是一个重复的问题,但我无法在片段中解决我的问题。在第一个片段中我有一个带有ProgressDialog的AsyncTask并且它重定向到第二个片段,在第二个片段中我按下设备后退按钮我在第一个片段中被泄露窗口异常。

我花了更多时间但是我无法得到解决方案。如何解决这个问题?请帮帮我。

这是我的第一个(MyAccount_MySpot)片段代码:

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();
        }

    }

}

完整日志代码:

 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)

3 个答案:

答案 0 :(得分:1)

使用

dialog = new ProgressDialog(getApplicationContext());

而不是

dialog = new ProgressDialog(getActivity());

答案 1 :(得分:0)

你正走在一条永远不会产生可行解决方案的道路上。 AsyncTasks通常比活动和对话的生命周期更长(在内存中)。听起来包含AsyncTask创建的对话框的活动正在消亡,因此,报告对话框拥有的窗口从未被删除。

如果您在Google上进行搜索,可以使用各种解决方案与AsyncTasks一起显示进度对话框。实现目标的一种相对简单的方法是让异步任务在保留的DialogFragment内运行,该对话框显示进度对话框。

答案 2 :(得分:0)

如果您使用的是AsyncTask,则必须执行一些Activity / Fragment生命周期管理。据报道,AsyncTasks是Android崩溃的主要原因之一。原因通常是在AsyncTask仍在运行时,当Activity自行关闭时,尝试执行与UI相关的操作

有几种方法可以做到这一点。在某些情况下,Activity.isFinishing()和Activity.isDestoryed()可能适用于您,也可能不适合您,因为它需要某个Android版本。另一种方法是保持像

这样的变量

boolean mShowStuffInAsyncTask = false;

将on设置为true onStart()或onResume(),并将onStop()或onPause()设置为false。当然,使用onStop()配对onStart(),使用onResume()配对onPause()。这个变量会告诉你在UI线程上做东西是否安全