2016-09-05 1 views
0

J'utilise JSONRequest de la bibliothèque volée, en arrière-plan comme AsyncTask() ...fenêtre fuite en utilisant volley

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

} 

Et l'erreur que je reçois est ...

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

Toute idée, ...

J'ai lu réponse https://stackoverflow.com/a/2850597/3099185 que je trouvais un peu pertinent, mais incapable de trouver une solution pour ma situation

Il ya aussi another link is available, mais je ne peux pas généraliser comme ça, car chaque classe gère les données différemment!?! ?? !!?

Merci d'avance!

+0

vous obtenez l'erreur en raison de cette ava.lang.IllegalArgumentException: View = com.android.internal.policy.impl.PhoneWindow $ DecorView {3d416b1c .... R ...... VE D 0 , 0-729,324} pas attaché au gestionnaire de fenêtres, cliquez sur logcat et voir quelle méthode provoque un crash. – W4R10CK

+0

Selon le code si vous voyez 'else else if (response.equals (" fail ")) {// déconnecte l'utilisateur et redirige vers l'écran de connexion}' Où un autre loginTask.java est appelé ayant la même structure que DataTask java 'public class DataTask étend AsyncTask {' ... Parfois, je reçois une erreur de ce seulement, je suis un peu comme il essaie d'accéder à la 'ProgressDialog pd' mais jusqu'à ce que la tâche a été fini et l'activité a également été changée ... – Bhuro

Répondre

1

Écrivez if(pd.isShowing()) { pd.hide(); } dans onPostExecute() et supprimez tous les énoncés connexes progressDialog de doInBackground().

Cette erreur est parce que dans AsyncTaskonPreExecute() et onPostExecute() fonctionne sur main thread et doInBackground() fonctionne sur différents thread. Si vous manipulez UI opérations liées à partir d'un autre thread de Main Thread alors votre fenêtre sera divulguée.

+0

J'ai essayé cela aussi, et dans ce cas le 'pd' se ferme en quelques millisecondes de' pd.show() 'parce que le JSONRequest est traité en arrière-plan, séparément, selon volley, out postExecution() sera appelé earler les données que j'ai eues dans '..new Response.Listener () {@Overide public void onResponse (réponse JSONObject) {... if (response.equals (" succès ")) {' ... :( – Bhuro

+0

Donc, si je reçois tout erreur ou exception dans 'Response.Listener () .. {' ou dans '}, nouvelle Response.ErrorListener() {' ... l'utilisateur devient confus car 'progreesDialog' a été fermé plus tôt mais l'écran n'est pas mis à jour avec de nouvelles données ...donc il effectue d'autres opérations avec un sens qu'il n'y avait pas de données de la demande précédente, et il essaie de faire de plus en plus demande ... – Bhuro

+0

Merci pour la réponse. Cette réponse peut être utile, mais mon cas était un peu différent. Et j'ai trouvé que Retrofit est beaucoup mieux et plus rapide que Volley. Accepter votre réponse car elle est plus pertinente pour l'optimisation de la pile d'exécution. – Bhuro

1

@Bhuro Je suis tombé sur ceci en cherchant une solution à un problème similaire. J'ai réussi à obtenir une solution, l'erreur est en fait en utilisant pDialog.hide() au lieu de pDialog.dismiss(). Dans le cas où quelqu'un d'autre rencontre un tel problème, initialisez le dialogue de progression comme ci-dessous;

ProgressDialog pDialog=new ProgressDialog(YourActivity.this); 

ensuite dans rejeter la méthode de réponse de volley-ball ou méthode erreur, avant de quitter la méthode jsonRequest, tout comme il est dans le code de la question OP ci-dessus. Mes méthodes pDialog sont comme;

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

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

Aussi, j'ai appelé la méthode rejeter dans la méthode OnDestroy activité;

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

Merci pour la réponse, ma classe asynctask est dans un package différent, où le vôtre est dans la même activité. Donc, je ne peux pas utiliser pour mon application. En passant, j'ai changé ma préférence d'utiliser Volly => Retrofit ... Mais cela peut être utile à quelqu'un qui est débutant ... – Bhuro