Activity has leaked window while using volley
Asked Answered
Y

2

0

I am using JSONRequest from volley library, in background as 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) {...}

}

And the error I am getting is ...

....
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)

Any idea, ...

I have read answer of https://mcmap.net/q/45412/-activity-has-leaked-window-that-was-originally-added which I found somewhat relevant, but unable to find solution for my situation

There is also another link is available , but I can't generalize like that calls, as my each class is handling data differently !?!??!!?

Thanks, in advance!

Yasmineyasu answered 5/9, 2016 at 14:35 Comment(2)
you are getting error due to this ava.lang.IllegalArgumentException: View=com.android.internal.policy.impl.PhoneWindow$DecorView{3d416b1c V.E..... R......D 0,0-729,324} not attached to window manager, click on logcat and see which method causeing crash.Thaler
As per the code if you see at }else if(response.equals("fail")){ // logout the user and redirect to login screen } Where another loginTask.java is getting called having the same structure as DataTask.java public class DataTask extends AsyncTask<String, Void, Void> { ... Some times I am getting error from that only, I got somewhat like it tries to access the ProgressDialog pd but till that the task has been finished and activity also have been changed ...Yasmineyasu
M
1

Write if(pd.isShowing()) { pd.hide(); } in onPostExecute() and remove all progressDialog related statements from doInBackground().

This error is because in AsyncTask onPreExecute() and onPostExecute() runs on main thread and doInBackground() runs on different thread. If you will handle UI related operations from another thread than Main Thread then your window will be leaked.

Muttonchops answered 5/9, 2016 at 14:48 Comment(3)
I have tried that also, and in that case the pd is getting closed within few milliseconds of pd.show() because the JSONRequest is getting handled in background, separately, as per volley, out postExecution() will be getting called earler the I got data in ..new Response.Listener<JSONObject>() { @Override public void onResponse(JSONObject response) { ... if (response.equals("success")) { ... :(Yasmineyasu
So If I am getting any error or exception in ` Response.Listener<JSONObject>() ..{` or in }, new Response.ErrorListener() { ... the user is getting confused as the progreesDialog was closed earlier but screen isn't updated with new data ... so he performs some other operations with a meaning that there was no data of previous request, and he tries to make more and more request ...Yasmineyasu
Thanks for answer. This answer can be useful, but mine cas was little different. And I have found that Retrofit is much better and faster then Volley. Accepting your answer as it is more relevant to execution stack optimization.Yasmineyasu
P
1

@Bhuro I came across this while searching for a solution to a similar problem.I managed to get a solution, the mistake is actually using pDialog.hide() instead of pDialog.dismiss(). In case anyone else encounters such a problem, initialize the Progress Dialog as below;

ProgressDialog pDialog=new ProgressDialog(YourActivity.this);

Then dismiss it in the volley Response method or Error method, before exiting the jsonRequest method, just like it is in the OP question's code above. My pDialog methods are as;

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

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

Also, I called the dismiss method in the Activity onDestroy method;

  @Override
public void onDestroy(){
    super.onDestroy();
    if(pDialog!=null){
        hideDialog();
    }
}
Phlebitis answered 17/2, 2017 at 0:46 Comment(1)
Thanks for the answer, my asynctask class is in different package,where as yours one is inside the same activity. So Can't use for my app. By the way, I have changed my preference from using Volly => Retrofit ... But this can be useful to someone who is beginner ...Yasmineyasu

© 2022 - 2024 — McMap. All rights reserved.