2015-06-30 12 views
6

Questo è il mio codice:Android come ottenere la stringa di risposta da Callback usando OkHttp?

OkHttpClient okHttpClient = new OkHttpClient(); 

    Request request = new Request.Builder().url("http://publicobject.com/helloworld.txt").build(); 

    Callback callback = new Callback() { 
     @Override 
     public void onFailure(Request request, IOException e) { 

     } 

     @Override 
     public void onResponse(Response response) throws IOException { 

     } 
    }; 

    okHttpClient.newCall(request).enqueue(callback); 

    String responseString; 

Nel codice di cui sopra, voglio per memorizzare il valore di response.body() string() dal metodo onResponse() nella responseString variabile, tuttavia posso'. t accedervi.

+1

Sono un po 'confuso di quello che stai cercando di fare qui. Se questo codice esiste in una funzione locale, allora a cosa serve fare un callback asincrono e memorizzare una variabile dichiarata nella funzione chiamante? Non saresti in grado di usarlo comunque a meno che non blocchi prima. È possibile memorizzare la risposta in una variabile di istanza di classe invece che funzionerebbe correttamente. Più che probabile se stai andando su questo nel modo sbagliato. –

+0

@MattWolfe hai probabilmente ragione, io sono nuovo allo sviluppo Android. Quello che sto cercando di fare è ottenere alcuni dati come questo [collegamento] (https://hacker-news.firebaseio.com/v0/topstories.json), salvarlo in una variabile, analizzarlo e quindi visualizzarlo sullo schermo usando una vista. La memorizzazione dei dati in una variabile di istanza sarebbe il modo giusto per farlo o c'è un altro modo? Grazie. –

+0

Avrei solo il tuo attrezzo attività/frammento Richiamata: Quindi fare: okHttpClient.newCall (request) .enqueue (this); Quindi nella tua risposta onResponse si può visualizzare i risultati sullo schermo. –

risposta

4

Penso che ciò che si vuole fare è qualcosa di simile:

public class MyActivity extends Activity implements Callback , View.OnClickListener { 


@Override 
public void onCreate(Bundle savedState) { 
    super.onCreate(savedState); 
    findViewById(R.id.DoHttp).setOnClickListener(this); 
} 

@Override 
public void onClick(View v) { 
    if (v.getId(() == R.id.DoHttp) { 

    OkHttpClient okHttpClient = new OkHttpClient(); 

    Request request = new Request.Builder().url("http://publicobject.com/helloworld.txt").build(); 
    okHttpClient.newCall(request).enqueue(this); 
    } 
} 


@Override 
public void onFailure(Request request, IOException e) { 
    //do something to indicate error 
} 

    @Override 
    public void onResponse(Response response) throws IOException { 
    if (response.isSuccessful()) { 
    parse(response.body().string()); 
    } 
    } 

    private void parse(String response) { 
    //do something with response 
    } 
} 

Nell'attività di cui sopra implementiamo Richiamata e poi quando creiamo la richiesta okhttp, passiamo esso un esempio di noi stessi (questo) e in questo modo possiamo ottenere oktthp per richiamare la classe, avremmo potuto fare una classe interna con la stessa facilità, ma questo riduce il numero di classi che dobbiamo fare. Ho usato un clic del pulsante per illustrare quando viene effettuata la chiamata Http, ma potrebbe essere un'altra volta, ad esempio potrebbe accadere quando lo schermo viene creato per la prima volta (in onCreate). Fai attenzione però alle rotazioni dello schermo. Anche questo presuppone che la callback sia fatta sul thread principale che penso sarebbe, ma non sono positivo dato che uso okttp in modo diverso da te. Se non restituisce i risultati sulla risposta sul thread principale, puoi chiamare runOnUiThread() e passargli un Runnable che esegue il lavoro di aggiornamento delle viste.

+0

Puoi pubblicare un esempio/link di qualcosa che tu userebbe, perché il metodo di cui sopra come hai detto eseguirà la chiamata di rete ogni volta sulla rotazione dello schermo giusto? –

+0

Questo è un problema comune senza una soluzione singola o semplice. –

+0

https://medium.com/google-developers/making-loading-data-on-android-lifecycle-aware-897e12760832 –

2

Se si sposta la dichiarazione responseString come variabile di istanza, sarà possibile assegnarne il valore nel metodo onResponse del proprio Callback.

public class MyClass { 

    private String responseString; 

    // your class implementation 

} 

Ho modificato il codice che avete inviato con le necessarie modifiche di seguito:

OkHttpClient okHttpClient = new OkHttpClient(); 

Request request = new Request.Builder().url("http://publicobject.com/helloworld.txt").build(); 

Callback callback = new Callback() { 
    @Override 
    public void onFailure(Request request, IOException e) { 

    } 

    @Override 
    public void onResponse(Response response) throws IOException { 
     responseString = response.body().string(); 
    } 
}; 

okHttpClient.newCall(request).enqueue(callback); 
+0

Purtroppo non riesco a cambiare il valore di responseString dentro onResponse dato che è definitivo –

+0

Sei perfettamente corretto, scusa per l'errore. Ho modificato il mio codice ma se non è più utile lo rimuoverò. –

+0

Grazie. Si scopre che il codice funziona, tuttavia ci vuole un po 'per il valore di responseString per essere aggiornato. –

1

Prima risposta è vicino, ma non è possibile assegnare variabili finale nel metodo onResponse. Soluzione è quello di digitare final String[] responseString = new String[1]; e assegnare responseString[0] = response.body().string();

+0

Dopo aver modificato il mio codice, https://gist.github.com/taimoor-ahmad/ef9515751294d80d460e ottengo java.lang.NullPointerException: println ha bisogno di un messaggio quando si tenta di utilizzare il valore di responseString [0] nel mio log –

+0

perché il codice in onResponse non è stato ancora richiamato, è necessario stamparlo dopo l'esecuzione di callback – Tomek

Problemi correlati