2016-04-24 2 views
-1

Я пытаюсь запросить API, чтобы получить ответ JSON и сохранить ответ в ArrayList.Тело ответа JSON не получено от OkHttp Callback

Этот ArrayList будет позже использоваться для настройки RecyclerView.

Я получаю ответ, если я зарегистрирую OnResponse() метод от OkHttp. Но когда я получаю ответ в моем фрагменте в виде строки через возвращение в OkhttpHandler то значение строки принимается в качестве нулевой

Вот код

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 для построения URL

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"; 
    } 

Вот URL, который я запрашивая http://api.themoviedb.org/3/discover/movie?api_key=a98debe57ccd9b42fe6b99b9014c80e3&sort_by=popularity.desc

ответ

0

Call#enqueue асинхронный API OkHttp в. Это означает, что запрос будет обрабатываться в фоновом потоке, и вызывающий поток будет продолжать работать с ИЛИ без запуска обратного вызова.

Чтобы использовать данные, вам необходимо либо использовать некоторую форму Future (ListenableFuture гуавы или RxJava может работать), чтобы ответить на возможной доступности данных или использовать Call#execute() вместо Call#enqueue сделать вызов синхронным способом ,

+0

Данные успешно быть неправдоподобным, он появляется на бревне, но строка jsonData = response.body() строка(). как-то всегда имеет значение null. jsonData должен иметь ответ в строковом формате, так как он был успешно зарегистрирован. Не так ли? –

+0

Нет, не должно. У вас есть идея, что код будет выполнен в том порядке, в котором вы его определили. Поскольку 'Call # enqueue' является асинхронным, вызов Callback' может быть выполнен в любой момент в будущем. 'String jsonData = response.body(). String(); 'просто не был выполнен в том месте, где вы делаете' return jsonData; ' – Kiskae

+0

. Не могли бы вы рассказать мне, что будет возможной работой, чтобы отправить тело ответа на вызывающую деятельность? –

0

Дело в том, что вы получаете доступ к переменной jsonData до того, как сетевая операция завершится и поместите что-то в нее. Это очень маловероятно.

Используйте что-то вроде Bus Event (мне нравится зеленый робот), и после события, когда jsonData есть что-то, сразу после линии jsonData = response.body().string();

И слушать это событие в вашем фрагменте пользовательского интерфейса, и заполнить данные один раз вы получаете это событие.

До этого покажите диалог прогресса/пользовательский интерфейс.

Таким образом, ваш код будет оставаться асинхронным, и вы получите это сделать, а

Смежные вопросы