2016-04-03 7 views
0

Ich verwende Volley, um JSON-Daten zu laden.App stürzt ab, wenn onResponse aufgerufen wird

Dies ist MainActivity

public class MainActivity extends AppCompatActivity 
     implements NavigationView.OnNavigationItemSelectedListener { 

    private final String TAG = "MainActivity"; 


    //Creating a list of posts 
    private List<PostItems> mPostItemsList; 

    //Creating Views 
    private RecyclerView recyclerView; 
    private RecyclerView.Adapter adapter; 
    private RecyclerView.LayoutManager layoutManager; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     Log.d(TAG, "Device rotated and onCreate called"); 

     //Initializing Views 
     recyclerView = (RecyclerView) findViewById(R.id.post_recycler); 
     layoutManager = new LinearLayoutManager(this); 
     recyclerView.setLayoutManager(layoutManager); 


     //Initializing the postlist 
     mPostItemsList = new ArrayList<>(); 
     adapter = new PostAdapter(mPostItemsList, this); 

     recyclerView.setAdapter(adapter); 

     if (NetworkCheck.isAvailableAndConnected(this)) { 
      //Caling method to get data 
      getData(); 
     } else { 
      final Context mContext; 
      mContext = this; 
      final AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this); 
      alertDialogBuilder.setTitle("No Internet Connection"); 
      alertDialogBuilder.setMessage("Failed to load. Please ensure you're connected to the internet and try again."); 
      alertDialogBuilder.setPositiveButton("Retry", new DialogInterface.OnClickListener() { 
       @Override 
       public void onClick(DialogInterface dialog, int which) { 
        if (!NetworkCheck.isAvailableAndConnected(mContext)) { 
         alertDialogBuilder.show(); 
        } else { 
         getData(); 
        } 


       } 
      }); 
      alertDialogBuilder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() { 
       @Override 
       public void onClick(DialogInterface dialog, int which) { 
        finish(); 

       } 
      }); 
      alertDialogBuilder.show(); 

     } 

    } 

    //This method will get data from the web api 
    private void getData(){ 

     Log.d(TAG, "getData called"); 
     //Showing progress dialog 
     final ProgressDialog progressDialog = ProgressDialog.show(this, null, "Loading posts", false, false); 

     //Creating a json request 
     JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(ConfigPost.GET_URL, 
       new Response.Listener<JSONArray>() { 
        @Override 
        public void onResponse(JSONArray response) { 
         Log.d(TAG, "onResponse called"); 
         //Dismissing the progress dialog 
         progressDialog.dismiss(); 


         //calling method to parse json array 
         parseData(response); 

        } 
       }, 
       new Response.ErrorListener() { 
        @Override 
        public void onErrorResponse(VolleyError error) { 

        } 
       }); 

     //Creating request queue 
     RequestQueue requestQueue = Volley.newRequestQueue(this); 

     //Adding request to the queue 
     requestQueue.add(jsonArrayRequest); 
    } 


} 

Wenn die App startet und ich es nicht drehen, es lädt & die JSON ganz in Ordnung analysiert; aber wenn die App startet und ich das Gerät mehrfach drehe, stürzt die App ab, sobald onResponse aufgerufen wird.

Dies ist der Stacktrace

04-03 12:46:10.493 22221-22221/com.example.poster D/MainActivity: Device rotated and onCreate called 
04-03 12:46:10.493 22221-22221/com.example.poster D/MainActivity: getData called 
04-03 12:46:11.234 22221-22221/com.example.poster D/MainActivity: Device rotated and onCreate called 
04-03 12:46:11.234 22221-22221/com.example.poster D/MainActivity: getData called 
04-03 12:46:12.675 22221-22221/com.example.poster D/MainActivity: Device rotated and onCreate called 
04-03 12:46:12.685 22221-22221/com.example.poster D/MainActivity: getData called 
04-03 12:46:14.096 22221-22221/com.example.poster D/MainActivity: Device rotated and onCreate called 
04-03 12:46:14.096 22221-22221/com.example.poster D/MainActivity: getData called 
04-03 12:46:15.278 22221-22221/com.example.poster D/MainActivity: Device rotated and onCreate called 
04-03 12:46:15.288 22221-22221/com.example.poster D/MainActivity: getData called 
04-03 12:46:15.448 22221-22221/com.example.poster D/MainActivity: onResponse called 
04-03 12:46:15.448 22221-22221/com.example.poster E/AndroidRuntime: FATAL EXCEPTION: main 
                    Process: com.example.poster, PID: 22221 
                    java.lang.IllegalArgumentException: View=com.android.internal.policy.impl.PhoneWindow$DecorView{7873bab V.E..... R......D 0,0-480,174} 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.example.poster.MainActivity$4.onResponse(MainActivity.java:142) 
                     at com.example.poster.MainActivity$4.onResponse(MainActivity.java:137) 
                     at com.android.volley.toolbox.JsonRequest.deliverResponse(JsonRequest.java:65) 
                     at com.android.volley.ExecutorDelivery$ResponseDeliveryRunnable.run(ExecutorDelivery.java:99) 
                     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:5910) 
                     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:1405) 
                     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1200) 

Von der stacktrace, Linie 142 ist progressDialog.dismiss(); und Linie 137 ist new Response.Listener<JSONArray>() {

Jede Idee, was dies verursacht werden könnte, und es ist Lösung?

UPDATE: Ich dachte daran, es zu codieren, so dass getData() nur aufgerufen wird, wenn die App zum ersten Mal erstellt wird. Dies liegt daran, dass getData() aufgerufen wird, wenn die Aktivität nach der Konfigurationsänderung (in diesem Fall Rotation) neu erstellt wird. Dadurch wird die Aktivität neu geladen. Ist das möglich? I.e. Um getData() nur beim ersten Mal aufzurufen, wird die Aktivität erstellt.

+0

setzen Sie Ihre parseData Code –

+0

Aber die Stacktrace hat noch keinen Hinweis auf parseData? Ist es wirklich nötig? Bitte korrigieren Sie mich, wenn ich falsch liege. – Faraday

+0

Ändern Sie 'final ProgressDialog progressDialog = ProgressDialog.show (this, null, "Posts laden", false, false); 'to' OnCreate() ' – Kathi

Antwort

5

Wenn App dreht, wird activity neu erstellt. Jetzt haben Sie die Instanz ProgressDialogprogressDialog. Wenn also die Aktivität rotiert, wird die alte Aktivität zerstört und somit wird diese Instanz progressDialog zerstört.

Nun wird die Aufgabe auf Hintergrund-Thread ausgeführt wird und wenn er zurückkehrt, könnte es nicht progressDialog finden, da es und damit zerstört wurde zur Zeit not attached to window manager (IllegalArgumentException).

So überprüfen besser die Instanz progressDialog bevor es onResponse zugreifen.

Try ProgressDialog wie folgt zu verwenden:

eine globale Instanz definieren: private ProgressDialog progressDialog;

In getData Methode:

private void getData(){ 

    Log.d(TAG, "getData called"); 
    //Showing progress dialog 
    progressDialog = new ProgressDialog(MainActivity.this); 
    progressDialog.setMessage("Loading posts"); 
    progressDialog.show(); 

In onResponse Rückruf:

if(progressDialog!=null){ 
    progressDialog.hide(); 
} 

onDestroy der Tätigkeit:

if(progressDialog!=null) progressDialog.dismiss(); // to prevent memory leak 
+0

Wie mache ich das? Und pls, ich habe die Frage aktualisiert. – Faraday

+0

Danke Sir! Es funktionierte wie Magie! Aber ich habe ein paar Fragen: Warum haben wir 'progressDialog.dismis()' nicht direkt von 'onResponse' aufgerufen und vergessen es in' onDestroy'? Und zweitens, kann ich nicht verhindern, dass 'getData()' aufgerufen wird, wenn die Aktivität nach einer Konfigurationsänderung neu erstellt wird? – Faraday

0

Sie müssen nur überprüfen, ist Objekt null, wenn Sie die progressdialog entlassen.

ProgressDialog progressDialog = ProgressDialog.show(this, null, "Loading posts", false, false); 

if(progressDialog!=null) 
progressDialog.dismiss();