0

我知道这是一个重复的问题,但我无法在片段中解决我的问题。在第一个片段中,我有一个带有 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)
4

3 回答 3

1

利用

dialog = new ProgressDialog(getApplicationContext());

代替

dialog = new ProgressDialog(getActivity());

于 2013-10-21T12:02:12.873 回答
0

如果您使用的是 AsyncTask,则必须进行一些 Activity/Fragment 生命周期管理。据报道,AsyncTasks 是导致 Android 崩溃的主要原因之一。原因通常是在 AsyncTask 仍在运行时,一旦 Activity 脱离了自身,就会尝试做一些与 UI 相关的事情

有几种方法可以做到这一点。有 Activity.isFinishing() 和 Activity.isDestoryed(),它们可能对你有用,也可能对你不起作用,在某些情况下,因为它需要特定的 Android 版本。另一种方法是保留一个变量

布尔 mShowStuffInAsyncTask = false;

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

于 2014-01-28T16:39:11.680 回答
0

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

如果您在 Google 上进行一些搜索,有多种解决方案可以结合 AsyncTasks 显示进度对话框。实现目标的一种相对简单的方法是让异步任务在显示进度对话框的保留 DialogFragment 中运行。

于 2013-10-18T19:05:42.003 回答