2015-12-14 7 views
7

Für meine App muss ich unsere API von unserem Server kontaktieren, die einige JSON zurückgibt.Android: Ergebnis aus Rückruf (Netzwerk KOUSH ION)

Beim Herunterladen des JSON sollte eine Fortschrittsanzeige angezeigt werden.

ich dachte, ich AsyncTask Android verwenden sollten, um die GUI zu handhaben, während Netzwerkoperationen zu tun, also schrieb ich folgendes: In meinem Activity:,

class DownloadManager extends AsyncTask<String, Void, Boolean> { 

    @Override 
    protected void onPreExecute() { 
     super.onPreExecute(); 
     mLoadingSpinner.setVisibility(View.VISIBLE); 
    } 

    @Override 
    protected Boolean doInBackground(String... params) { 
     String id = params[0]; 
     downloadUtility.getId(id); 

     return true; 
    } 

    @Override 
    protected void onPostExecute(Boolean result) { 
     super.onPostExecute(result); 

     mLoadingSpinner.setVisibility(View.INVISIBLE); 

    } 

} 

Grundsätzlich onPreExecute zeigt die Lade spinner die doInBackGround lädt einige JSON, und onPostExecute stoppt den Spinner.

Die Frage ist, in der downloadUtility.getId(id) Ich muss entweder:

  1. Öffnen Sie eine neue Absicht, wenn der Download gelungen.
  2. Bleiben Sie bei der gleichen Aktivität und zeigen Sie einen Fehler an toast, wenn der Download fehlgeschlagen ist.

Der Code für die getId:

public Future getId(final String id) { 
    // set url 
    String url = IPAddress.PRODUCTION + Variables.get_id+ id; 
    downloading = Ion.with(context) 
      .load("GET", url) 
      .asJsonObject() 
      .withResponse() 
      .setCallback(new FutureCallback<Response<JsonObject>>() { 
       @Override 
       public void onCompleted(Exception e, Response<JsonObject> response) { 
        //try catch here for null getHeaders 
        if (response != null) { 
         if (response.getHeaders().code() == 200) { 

          //SUCCESS !! Open new intent! 


         } else { 
          //FAIL!! Show TOAST! 
         } 
        } 

       } 
      }); 


    return downloading; 

} 

Wie Sie sehen, ich bin ein zukünftiges Objekt zurück. Woher weiß ich aus dem zukünftigen Objekt, ob die onCompleted (void) entweder erfolgreich war oder fehlgeschlagen ist, damit ich das Ergebnis (Erfolg: neue Absicht öffnen, fehlschlagen: Toast) in der asynctask behandeln kann?

Antwort

3

Ich glaube nicht, dass Sie AsyncTask für den Netzwerkbetrieb benötigen, weil Ihre Ionenbibliothek intern bereits asynctask verwendet. Sie können

mLoadingSpinner.setVisibility(View.VISIBLE); 
downloading = Ion.with(context) 
      .load("GET", url) 
      .asJsonObject() 
      .withResponse() 
      .setCallback(new FutureCallback<Response<JsonObject>>() { 
       @Override 
       public void onCompleted(Exception e, Response<JsonObject> response) { 
        //try catch here for null getHeaders 
        if (response != null) { 
         if (response.getHeaders().code() == 200) { 

          //SUCCESS !! Open new intent! 
          mLoadingSpinner.setVisibility(View.INVISIBLE); 
         } else { 
          mLoadingSpinner.setVisibility(View.INVISIBLE); 
         } 
        } 

       } 
      }); 
    return downloading; 

wie dies tun lassen Sie mich, wenn einige Themen wissen.

+0

Bedeutet das nicht, dass Sie Download-Code innerhalb einer Aktivitätsklasse schreiben würden? Der Grund, aus dem ich eine DownloadUtility-Klasse erstellt habe, besteht darin, die gesamte Tatsache loszuwerden, um den Download-Code in eine Aktivität zu integrieren, und sie in eine Klasse zu stellen, in die sie gehört. –

+1

yeah eine separate Klasse und in einer Funktion fügen Sie diesen Code, damit Sie es trennen können – Rahul

+0

Wenn ich eine separate Klasse machen würde, wäre ich nicht in der Lage, die mloadingSpinner aufrufen, da die Klasse keine Aktivität ist. Ich könnte den loadingspinner in den Konstruktor des downloadUtility-Objekts übergeben, aber das wäre nicht der beste Weg. (Ich habe das einmal versucht). Auch, um eine neue Absicht von einem Nicht-Aktivität zu öffnen, müsste ich eine FLAG verwenden, um eine neue Aktivität aus einer normalen Klasse zu öffnen .. was ist kein netter Code –

6

Hier führen Sie eine asynctask in einer anderen asyctask aus Dies ist keine ordentliche Möglichkeit, Ihre getId-Methode direkt in Ihrer Aktivität aufzurufen, es wird keine weitere asynctask benötigt, da der folgende Code selbst eine asynctask ist.

downloading = Ion.with(context) 
     .load("GET", url) 
     .asJsonObject() 
     .withResponse() 
     .setCallback(new FutureCallback<Response<JsonObject>>() { 
      @Override 
      public void onCompleted(Exception e, Response<JsonObject> response) { 
       //try catch here for null getHeaders 
       if (response != null) { 
        if (response.getHeaders().code() == 200) { 

         //SUCCESS !! Open new intent! 


        } else { 
         //FAIL!! Show TOAST! 
        } 
       } 

      } 
     }); 

// hinzufügen Antwort

Wenn Sie getrennt von Ihrer Aktivität gesamten Download-Code wollen, dann können Sie benutzerdefinierten Rückruf des Download Utility-Klasse erstellen. Es verhält sich wie ein Kommunikator zwischen Aktivität und Ihrem Download-Kurs. Ich gebe nur einen Weg, diese Aufgabe zu erledigen.

DownloadUtility Klasse Nähte aussehen wie unten

public class DownloadUtility { 


//DO Your all other Stuff 

/** 
* Custom Callback 
*/ 
public interface customCallBack { 
    void onCompleted(Exception e, Response<JsonObject> response); 
} 


/** 
* Your getID code 
* 
* @param context 
* @param id 
* @param mLoadingSpinner 
* @param callBack 
*/ 
public static void getId(Activity context,final String id, Spinner mLoadingSpinner, final customCallBack callBack) { 
    // set url 
    mLoadingSpinner.setVisibility(View.VISIBLE); 
    String url = IPAddress.PRODUCTION + Variables.get_id + id; 
    downloading = Ion.with(context) 
      .load("GET", url) 
      .asJsonObject() 
      .withResponse() 
      .setCallback(new FutureCallback<Response<JsonObject>>() { 
       @Override 
       public void onCompleted(Exception e, Response<JsonObject> response) { 
        mLoadingSpinner.setVisibility(View.GONE); 
        if(callBack != null) 
        callBack.onCompleted(e,response); 
        } 
       } 
      }); 
} 

}

einen Anruf auf Ihrem Aktivität

DownloadUtility.getId(this, "ID", spinnerObj, new DownloadUtility.customCallBack() { 
@Override 
public void onCompleted(Exception e, Response<JsonObject> response) { 
    if (response != null) { 
     if (response.getHeaders().code() == 200) { 
      //SUCCESS !! Open new intent! 
     } else { 
      //FAIL!! Show TOAST! 
     } 
} 

}) machen;

+0

Würde das nicht bedeuten dass Sie Download-Code in einer Aktivitätsklasse schreiben würden? Der Grund, aus dem ich eine DownloadUtility-Klasse erstellt habe, besteht darin, die gesamte Tatsache loszuwerden, um den Download-Code in eine Aktivität zu integrieren, und sie in eine Klasse zu stellen, in die sie gehört. –

+0

Ich habe einige Änderungen in der Antwort nach Ihrer Anforderung gemacht, ich hop es kann Ihnen helfen. –

+0

Im obigen Code möchten Sie nicht mLoadingSpinnerObject übergeben, Sie können es in der Aktivität selbst starten, Sie können es vor dem Aufruf dieser Funktion starten und onComplete können Sie stoppen. –

0

Meiner Meinung nach ist die sauberste Lösung, einen Dienst zu erstellen, der die Dirty-Download-Logik verarbeitet und eine Zukunft Ihrer benutzerdefinierten Antwortklasse zurückgibt, die die Erfolgsinformationen und das Json-Objekt enthält.

// in e.g JsonResponse.java 
public class JsonResponse() { 
    public boolean ok; 
    public JsonObject json; 
} 

// in Service.java 
public Future<JsonResponse> getId(final String id) { 
    final SimpleFuture<JsonResponse> jsonFuture = new SimpleFuture<>(); 

    String url = IPAddress.PRODUCTION + Variables.get_id + id; 
    Ion.with(context) 
    .load("GET", url) 
    .asJsonObject() 
    .withResponse() 
    .setCallback(new FutureCallback<Response<JsonObject>>() { 
     @Override 
     public void onCompleted(Exception e, Response<JsonObject> response) { 
      JsonResponse jsonResponse = new JsonResponse(); 
      if (response != null) { 
       if (response.getHeaders().code() != 200) { 
        jsonResponse.ok = false; 
       } else { 
        jsonResponse.ok = true; 
        jsonResponse.json = response.getResult(); 
       } 
      } 
      jsonFuture.setComplete(jsonResponse); 
     } 
    }); 

    return jsonFuture; 
} 


// in Activity.java 
private void loadUser(String userId) {  
    mLoadingSpinner.setVisibility(View.VISIBLE); 

    service.getId(userId) 
    .setCallback(new FutureCallback<JsonResponse>() { 

     // onCompleted is executed on ui thread 
     @Override 
     public void onCompleted(Exception e, JsonResponse jsonResponse) { 
      mLoadingSpinner.setVisibility(View.GONE); 
      if (jsonResponse.ok) { 
       // Show intent using info from jsonResponse.json 
      } else { 
       // Show error toast 
      } 
     } 
    }); 
} 
+0

Ich habe den Code nicht getestet, ich hoffe es gibt keine großen Mistkases :) – ronkot

Verwandte Themen