android volley 使用凌空時,活動已經洩漏




volley usage (2)

我使用從排球庫JSONRequest,背景為Asynctask()...

public class DataTask extends AsyncTask<String, Void, Void> {
    public static ProgressDialog pd;
    ...

    public DataTask(Context ctx,...) {
    ...
        pd = new ProgressDialog(context);
       ...
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        pd.setTitle("Please wait...");
        pd.show();
    }

    @Override
    protected Void doInBackground(String... params) {
        ...
        Log.d(TAG, " url=" + url);
        JSONRequest jsonObjReq = new JSONRequest(Request.Method.GET, url, null,
                 new Response.Listener<JSONObject>() {
            @Override
            public void onResponse(JSONObject response) {
                ...
                if (response.equals("success")) {
                ...
                }else if(response.equals("fail")){
                    // logout the user and redirect to login screen
                }
                Log.d(TAG, " -> pd.isShowing() = " + pd.isShowing());
                if (pd.isShowing()) { pd.hide(); }
                ...
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                error.printStackTrace();
                pd.hide();
            }
        });
        ...
        // Adding request to request queue
        App.Instance().addToQueue(jsonObjReq);
        return null;
    }

    @Override
    protected void onPostExecute(Void data) {...}

}

而我得到的錯誤是...

....
E/WindowManager: android.view.WindowLeaked: Activity com.volley.exmpl.DataViewActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView{3d416b1c V.E..... R......D 0,0-729,324} that was originally added here
                     at android.view.ViewRootImpl.<init>(ViewRootImpl.java:363)
                     at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:271)
                     at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:85)
                     at android.app.Dialog.show(Dialog.java:298)
                     at com.volley.exmpl.Task.LoginTask.onPreExecute(LoginTask.java:43)
                     at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:591)
                     at android.os.AsyncTask.execute(AsyncTask.java:539)
                     at com.volley.exmpl.DataViewActivity.callLogin(DataViewActivity.java:281)
                     at com.volley.exmpl.DataViewActivity.ondataViewCompleted(DataViewActivity.java:283)
                     at com.volley.exmpl.Task.DataTask$1.onResponse(DataTask.java:210)
                     at com.volley.exmpl.Task.DataTask$1.onResponse(DataTask.java:112)
                     at com.android.volley.toolbox.JsonRequest.deliverResponse(JsonRequest.java:68)
                     at com.android.volley.ExecutorDelivery$ResponseDeliveryRunnable.run(ExecutorDelivery.java:113)
                     at android.os.Handler.handleCallback(Handler.java:739)
                     at android.os.Handler.dispatchMessage(Handler.java:95)
                     at android.os.Looper.loop(Looper.java:135)
                     at android.app.ActivityThread.main(ActivityThread.java:5254)
                     at java.lang.reflect.Method.invoke(Native Method)
                     at java.lang.reflect.Method.invoke(Method.java:372)
                     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
                     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
D/TAG_Act: onStop()-> className::close ListActivity
D/AndroidRuntime: Shutting down VM
....
                  --------- beginning of crash
E/AndroidRuntime: FATAL EXCEPTION: main
                  Process: com.volley.exmpl, PID: 29825
                  java.lang.IllegalArgumentException: View=com.android.internal.policy.impl.PhoneWindow$DecorView{3d416b1c V.E..... R......D 0,0-729,324} not attached to window manager
                      at android.view.WindowManagerGlobal.findViewLocked(WindowManagerGlobal.java:396)
                      at android.view.WindowManagerGlobal.removeView(WindowManagerGlobal.java:322)
                      at android.view.WindowManagerImpl.removeViewImmediate(WindowManagerImpl.java:116)
                      at android.app.Dialog.dismissDialog(Dialog.java:341)
                      at android.app.Dialog.dismiss(Dialog.java:324)
                      at com.volley.exmpl.Task.LoginTask$1.onResponse(LoginTask.java:120)
                      at com.volley.exmpl.Task.LoginTask$1.onResponse(LoginTask.java:71)
                      at com.android.volley.toolbox.JsonRequest.deliverResponse(JsonRequest.java:68)
                      at com.android.volley.ExecutorDelivery$ResponseDeliveryRunnable.run(ExecutorDelivery.java:113)
                      at android.os.Handler.handleCallback(Handler.java:739)
                      at android.os.Handler.dispatchMessage(Handler.java:95)
                      at android.os.Looper.loop(Looper.java:135)
                      at android.app.ActivityThread.main(ActivityThread.java:5254)
                      at java.lang.reflect.Method.invoke(Native Method)
                      at java.lang.reflect.Method.invoke(Method.java:372)
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)

任何想法, ...

我已閱讀https://stackoverflow.com/a/2850597/3099185的答案,我發現有點相關,但無法找到我的情況的解決方案

還有另一個鏈接是可用的 ,但我不能像這樣的調用一般化,因為我的每個類正在處理不同的數據!?!?? !!?

提前致謝!


if(pd.isShowing()) { pd.hide(); } if(pd.isShowing()) { pd.hide(); }onPostExecute()並從doInBackground()刪除所有progressDialog相關的語句。

這個錯誤是因為在AsyncTask onPreExecute()onPostExecute()main thread上運行, doInBackground()在不同的thread上運行。 如果你要處理來自另一個thread UI相關的操作,那麼你的窗口將被洩漏。


@Bururo我遇到了這個問題,同時尋找解決類似的問題。我設法得到一個解決方案,錯誤實際上是使用pDialog.hide()而不是pDialog.dismiss()。 如果有其他人遇到這樣的問題,請按照以下步驟初始化進度對話框;

ProgressDialog pDialog=new ProgressDialog(YourActivity.this);

然後在退出jsonRequest方法之前,將其排除在響應方法或Error方法之外,就像它在上面的OP問題代碼中一樣。 我的pDialog方法是as;

private void showDialog(){
    if(!pDialog.isShowing())
        pDialog.show();
}

private void hideDialog(){
    if(pDialog.isShowing())
        pDialog.dismiss();
}

另外,我在Activity的onDestroy方法中調用了dismiss方法;

  @Override
public void onDestroy(){
    super.onDestroy();
    if(pDialog!=null){
        hideDialog();
    }
}




android-volley