2016-04-24 6 views
-1

Ich versuche, eine API abzufragen, um die JSON-Antwort abzurufen und die Antwort in einer ArrayList zu speichern.JSON-Antworttext wird nicht von OkHttp empfangen. Rückruf

Diese ArrayList wird später für die Einrichtung eines RecyclerView verwendet.

Ich bekomme die Antwort, wenn ich die OnResponse() Methode von OkHttp anmelden. Aber wenn ich als String über die Rück die Antwort in meinem Fragment empfange in der OkhttpHandler dann wird der String-Wert empfangen wird als null

Hier ist der Code

OkHttpHelper.Java

package com.execube.genesis.utils; 

import android.util.Log; 
import android.widget.Toast; 

import org.json.JSONArray; 
import org.json.JSONException; 
import org.json.JSONObject; 

import java.io.IOException; 

import okhttp3.Call; 
import okhttp3.Callback; 
import okhttp3.OkHttpClient; 
import okhttp3.Request; 
import okhttp3.Response; 

/** 
* Created by Prateek Phoenix on 4/24/2016. 
*/ 


public class OkHttpHandler { 

    private String queryUrl; 
    private String jsonData; 

    private static final String TAG = "CustomTAG1"; 



    public OkHttpHandler(String Url) { 
     this.queryUrl = Url; 
    } 

    public String fetchData() { 

     OkHttpClient client = new OkHttpClient(); 
     Request request = new Request.Builder() 
       .url(queryUrl) 
       .build(); 

     Call call = client.newCall(request); 
     call.enqueue(new Callback() { 
      @Override 
      public void onFailure(Call call, IOException e) { 
       Log.v(TAG, "Exception: ", e); 
      } 

      @Override 
      public void onResponse(Call call, Response response) throws IOException { 
       Log.v(TAG, response.body().string()); 

       if (response.isSuccessful()) { 

        jsonData = response.body().string(); 

       } 
      } 
     }); 

     return jsonData; //Even this is null when I check via Debugger 
    } 
} 

PopularMoviesFragment.java

package com.execube.genesis.views; 

import android.os.Bundle; 
import android.support.annotation.Nullable; 
import android.support.v4.app.Fragment; 
import android.util.Log; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.ProgressBar; 

import com.execube.genesis.R; 
import com.execube.genesis.model.Movie; 
import com.execube.genesis.utils.API; 
import com.execube.genesis.utils.OkHttpHandler; 

import org.json.JSONArray; 
import org.json.JSONException; 
import org.json.JSONObject; 

import java.util.ArrayList; 

/** 
* Created by Prateek Phoenix on 4/24/2016. 
*/ 
public class PopularMoviesFragment extends Fragment { 

    private static final String TAG = "CustomTAG"; 
    private ArrayList<Movie> mMovies; 

    private String jsonResponse; 


    @Override 
    public void onCreate(@Nullable Bundle savedInstanceState) { 
     mMovies=new ArrayList<>(); 

     String url= API.BASE_URL+API.API_KEY+API.SORT_POPULARITY; 

     OkHttpHandler handler= new OkHttpHandler(url); 
     jsonResponse=handler.fetchData(); 

     try { 
      mMovies= parseItems(jsonResponse); 
     } catch (JSONException e) { 
      Log.v(TAG,"Exception caught: ",e); 
     } 

     super.onCreate(savedInstanceState); 


    } 

    private ArrayList<Movie> parseItems(String jsonResponse) throws JSONException{ 

     JSONObject jsonData= new JSONObject(jsonResponse); 
     JSONArray moviesJSONArray= jsonData.getJSONArray("results"); 
     ArrayList<Movie> Movies= new ArrayList<>(); 
     for (int i = 0; i <moviesJSONArray.length() ; i++) { 

      Movie movie= new Movie(); 
      JSONObject movieJson= moviesJSONArray.getJSONObject(i); 

      movie.setId(movieJson.getInt("id")); 
      Log.v(TAG,"TITLE IS "+movieJson.getString("title")); 
      movie.setOriginalTitle(movieJson.getString("original_title")); 
      movie.setOverview(movieJson.getString("overview")); 
      movie.setPosterPath(movieJson.getString("poster_path")); 
      movie.setVoteAverage((float) movieJson.getDouble("vote_average")); 
      movie.setTitle(movieJson.getString("title")); 

      Movies.add(movie); 
     } 

     return Movies; 
    } 


    @Nullable 
    @Override 
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 
     View view= inflater.inflate(R.layout.fragment_popular_movies,container,false); 
     return view; 
    } 



} 

API.java die URL für den Aufbau

package com.execube.genesis.utils; 

/** 
* Created by Prateek Phoenix on 4/24/2016. 
*/ 
public class API { 


    public static String BASE_URL = "http://api.themoviedb.org/3/discover/movie?"; 
    public static String MOVIE_BASE_URL = "http://api.themoviedb.org/3/movie/"; 
    public static String API_KEY = "api_key=a98debe57ccd9b42fe6b99b9014c80e3"; 
    public static String SORT_POPULARITY = "&sort_by=popularity.desc"; 
    public static String SORT_R_RATED = "&certification_country=US&certification=R&sort_by=vote_average.desc&vote_count.gte=250"; 
    public static String IMAGE_URL = "http://image.tmdb.org/t/p/"; 
    public static String IMAGE_SIZE_185 = "w500"; 
    } 

Hier ist die URL, die ich http://api.themoviedb.org/3/discover/movie?api_key=a98debe57ccd9b42fe6b99b9014c80e3&sort_by=popularity.desc

Antwort

0

Call#enqueue ist OkHttp die asynchrone API am abfragt. Dies bedeutet, dass die Anforderung in einem Hintergrundthread verarbeitet wird und der aufrufende Thread weiterhin mit OR ausgeführt wird, ohne den Rückruf auszuführen.

die Daten zu verwenden, benötigen Sie entweder eine Form von Future zu verwenden (Guava des ListenableFuture oder RxJava funktionieren könnte) an die eventuellen Verfügbarkeit der Daten oder Call#execute()Call#enqueue statt verwenden, um zu reagieren, um den Anruf in einer synchronen Weise zu tun .

+0

Die Daten werden erfolgreich abgerufen wird getan, es auf dem Protokoll angezeigt wird, aber String jsonData = response.body() string(). ist irgendwie immer Null. jsonData sollte die Antwort im Zeichenfolgenformat haben, da es erfolgreich protokolliert wurde. Sollte es nicht? –

+0

Nein sollte es nicht. Sie haben die Idee, dass der Code in der Reihenfolge ausgeführt wird, in der Sie ihn definiert haben. Da 'Call # Enqueue' asynchron ist, kann der' Callback'-Aufruf zu irgendeinem Zeitpunkt in der Zukunft ausgeführt werden. 'String jsonData = response.body(). String(); 'wurde einfach nicht an dem Punkt ausgeführt, an dem Sie 'jsonData zurückgeben;' – Kiskae

+0

Nun, könnten Sie mir bitte sagen, was wäre eine mögliche Arbeit um den Antwortkörper an die aufrufende Aktivität zu senden? –

0

Das Problem ist, dass Sie auf die Variable jsonData zugreifen, bevor der Netzwerkvorgang beendet werden kann und etwas darin eingefügt werden kann. Das ist sehr unwahrscheinlich.

Verwendung so etwas wie ein Ereignis Bus (I Green Robot ist wie), und ein Ereignis hinzufügen, wenn die jsonData etwas hat, gleich nach der Linie jsonData = response.body().string();

Und zu diesem Ereignis in Ihrem UI-Fragment hören, und füllen Sie einmal Daten Du erhältst dieses Ereignis.

Bis dann, zeigen Sie den Fortschritt Dialog/UI.

Auf diese Weise Ihr Code bleibt async und Sie werden dies auch

Verwandte Themen