2017-11-29 2 views
0

Ich arbeite an einer Android-Anwendung, die vollständig von RESTful APIs abhängig ist. Fast jeder Bildschirm der Anwendung führt einen Netzwerkanruf durch. Ich verwende folgende Hilfsklasse für die Durchführung von Netzwerkanfragen.UnRegister Interface Callbacks, wenn Aktivität zerstört wird

import android.content.Context; 
import android.content.SharedPreferences; 
import android.preference.PreferenceManager; 
import android.util.Log; 

import com.android.volley.AuthFailureError; 
import com.android.volley.DefaultRetryPolicy; 
import com.android.volley.NetworkResponse; 
import com.android.volley.RequestQueue; 
import com.android.volley.Response; 
import com.android.volley.VolleyError; 
import com.android.volley.VolleyLog; 
import com.android.volley.toolbox.StringRequest; 
import com.android.volley.toolbox.Volley; 

import java.io.UnsupportedEncodingException; 
import java.util.HashMap; 
import java.util.Map; 

public class RequestHandler { 
    private final String deviceID; 
    private RequestQueue queue; 
    private StringRequest stringRequest; 
    private NetworkRequestListener networkRequestListener; 
    private NetworkResponseListener networkResponseListener; 
    private SharedPreferences sharedPreferences; 

    public RequestHandler(Context context) { 
     queue = Volley.newRequestQueue(context); 
     sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context); 
     deviceID = UtilityMethods.getDeviceId(context); 
    } 

    public void makeNetworkRequest(String url, int method, final String body) { 
     stringRequest = new StringRequest(method, appendedURL, 
       new Response.Listener<String>() { 
        @Override 
        public void onResponse(String response) { 
         Log.e("RESPONSE", response); 
         if (networkResponseListener != null) { 
          networkResponseListener.onResponseLoaded(response); 
         } 
        } 
       }, new Response.ErrorListener() { 
      @Override 
      public void onErrorResponse(VolleyError error) { 
       if (networkResponseListener != null) { 
        networkResponseListener.onResponseFailed(error); 
       } 
      } 
     }) { 
      @Override 
      public String getBodyContentType() { 
       return "application/json; charset=utf-8"; 
      } 

      @Override 
      public byte[] getBody() { 
       try { 
        return body.getBytes("utf-8"); 
       } catch (UnsupportedEncodingException | NullPointerException uee) { 
        VolleyLog.wtf("Unsupported Encoding while trying to get the bytes of %s using %s", body, "utf-8"); 
        return null; 
       } 
      } 

      @Override 
      public Map<String, String> getHeaders() throws AuthFailureError { 
       Map<String, String> headers = new HashMap<>(); 
       headers.put("version", AppConstants.VERSION); 
       headers.put("Content-Type", "application/json"); 
       return headers; 
      } 

      @Override 
      protected Response<String> parseNetworkResponse(NetworkResponse networkResponse) { 
       String response = UtilityMethods.networkResponseToString(networkResponse); 

       networkResponseListener.onResponseReceived(response); 
       return super.parseNetworkResponse(networkResponse); 
      } 
     }; 

     stringRequest.setShouldCache(false); 
     stringRequest.setRetryPolicy(new DefaultRetryPolicy(
       0, 
       DefaultRetryPolicy.DEFAULT_MAX_RETRIES, 
       DefaultRetryPolicy.DEFAULT_BACKOFF_MULT)); 
     if (networkRequestListener != null) { 
      networkRequestListener.beforeMakeRequest(stringRequest); 
     } 
     queue.add(stringRequest); 
    } 

    public void setNetworkResponseListener(NetworkResponseListener networkResponseListener) { 
     this.networkResponseListener = networkResponseListener; 
    } 

    public void setNetworkRequestListener(NetworkRequestListener networkRequestListener) { 
     this.networkRequestListener = networkRequestListener; 
    } 

    public RequestQueue getQueue() { 
     return queue; 
    } 

    public StringRequest getStringRequest() { 
     return stringRequest; 
    } 
} 

Jetzt Problem dabei ist, dass ich nicht für ein Verfahren Aware-Netzwerkanforderung abzubrechen (Einstellung Rückruf-Schnittstellen zu null ist nicht so gut funktioniert). Wenn die Antwort vom Netzwerkaufruf kommt, nachdem die Aktivität zerstört wurde, werfen die Handler-Methoden eine NPE, weil entweder der Kontext NULL ist oder eine Sicht (Obwohl die Aktivität zerstört ist, wird der Code noch ausgeführt). Gibt es eine Möglichkeit, eine Netzwerkantwort abzubrechen/zu ignorieren, wenn die Aktivität zerstört wird? Auch wenn diese Implementierung verbessert werden könnte, da fast jede Aktivität aufgrund dieser Klasse ein Speicherleck hat.

+0

Rahmen Rückruf-Schnittstellen zu null sind nicht so gut funktioniert. Können Sie mitteilen, wie Sie das umsetzen? –

Antwort

0

ein Verfahren in dieser Klasse erstellen, wie diese

public static final String TAG = "MyTag"; 
StringRequest stringRequest; // Assume this exists. 
RequestQueue queue; // Assume this exists. 

// Set the tag on the request. 
stringRequest.setTag(TAG); 

// Add the request to the RequestQueue. 
queue.add(stringRequest); 

public void cancelTag() { 
    return queue.cancelAll(TAG);; 
} 

Im Aufruf Aktivität onStop() diese CancelTag()

+0

Quelle: https://developer.android.com/training/volley/simple.html –

Verwandte Themen