Problem with threads on Android

0

I'm trying to get values from a json and play on a recycleview using OkHttp , it's getting values and playing in the list, without errors, however I'm not able to pass those values to the adapter, the list is getting null in fragment , I'm pretty sure the problem is with thread , probably the main thread is getting the value of the list before the thread of callback setar ...

How to solve?

Class where I get the json values: (I believe the problem is in the sendGetRecipes method)

public class HttpRequest {

    private List<Recipes> recipesList;

    public void sendGetRecipes(String url) {

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

        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                call.cancel();
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                String strResponse = response.body().string();
                setRecipesList(strResponse);
                Log.d("HTTP", "PASSOU!!!!!");
                Log.d("HTTP", strResponse);
            }
        });
    }

    public void setRecipesList(String response) {
        recipesList = new ArrayList<>();

        List<Ingredients> ingredientsList = new ArrayList<>();
        List<Steps> stepsList = new ArrayList<>();

        if (response != null) {
            try {

                JSONArray jsonArray = new JSONArray(response);

                for (int i = 0; i < jsonArray.length(); i++) {
                    JSONObject jsonObject = jsonArray.getJSONObject(i);
                    Recipes recipes = new Recipes();
                    recipes.setId(jsonObject.getInt("id"));
                    recipes.setName(jsonObject.getString("name"));
                    recipes.setImage(jsonObject.getString("image"));
                    recipes.setServings(jsonObject.getInt("servings"));

                    JSONArray ingrJsonArray = jsonObject.getJSONArray("ingredients");
                    for (int j = 0; j < ingrJsonArray.length(); j++) {
                        JSONObject ingrJsonObject = ingrJsonArray.getJSONObject(j);
                        Ingredients ingredients = new Ingredients();
                        ingredients.setIngredient(ingrJsonObject.getString("ingredient"));
                        ingredients.setMeasure(ingrJsonObject.getString("measure"));
                        ingredients.setQuantity(ingrJsonObject.getInt("quantity"));

                        ingredientsList.add(ingredients);
                        //Log.d("ARRAY-JSON-INGR", ingrJsonObject.getString("ingredient"));

                    }

                    JSONArray stepsJsonArray = jsonObject.getJSONArray("steps");
                    for (int j = 0; j < stepsJsonArray.length(); j++) {
                        JSONObject stepsJsonObject = stepsJsonArray.getJSONObject(j);
                        Steps steps = new Steps();
                        steps.setId(stepsJsonObject.getInt("id"));
                        steps.setDescription(stepsJsonObject.getString("description"));
                        steps.setShortDescription(stepsJsonObject.getString("shortDescription"));
                        steps.setVideoUrl(stepsJsonObject.getString("videoUrl"));
                        steps.setThumbnailUrl(stepsJsonObject.getString("thumbnailUrl"));

                        stepsList.add(steps);
                        //Log.d("ARRAY-JSON-INGR", ingrJsonObject.getString("ingredient"));

                    }

                    recipes.setIngredientsList(ingredientsList);
                    recipes.setStepsList(stepsList);

                    recipesList.add(recipes);
                }

            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
    }

    public List<Recipes> getRecipesList() {
        return recipesList;
    }
}

Fragment (I commented on where it tries to get the list)

public class MainFragment extends Fragment {

    private static final String TAG = MainFragment.class.getSimpleName();
    private RecyclerView recipesRecycleView;
    private List<Recipes> recipesList;

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

        recipesRecycleView = (RecyclerView) view.findViewById(R.id.recipesRecycleView);

        LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
        layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
        recipesRecycleView.setLayoutManager(layoutManager);

        HttpRequest httpRequest = new HttpRequest();
        httpRequest.setRecipesList(Recipes.RECIPES_URL);
        recipesList = httpRequest.getRecipesList();  // <------------- AQUI

        RecipesAdapter recipesAdapter = new RecipesAdapter(getActivity(), recipesList);
        recipesRecycleView.setAdapter(recipesAdapter);


        return view;
    }

}

I did not post the adapter code because the problem is not there

    
asked by anonymous 09.05.2017 / 06:54

1 answer

1

You can create an interface in your HttpRequest class with a callback method that will work with the list of recipes obtained.

public interface OnRecipesReady {
    public void getRecipes(List<Recipes> recipes);
}

Create a handler variable to use the interface in the same class and a constructor to get a reference from your Fragment:

private OnRecipesReady handler;

public HttpRequest(OnRecipesReady h){
   handler = h;
}

In the setRecipesList () method after for and before catch, add this line:

handler.getRecipes(recipesList);

In your Fragment implement the interface and the callback method and pass the creation of the Adapter and association in the RecyclerView to the Adapter:

public class MainFragment extends Fragment implements OnRecipesReady {

 ...

   @Overide
   public void getRecipes(List<Recipes> recipes){
        recipesAdapter = new RecipesAdapter(getActivity(), recipes);
        recipesRecycleView.setAdapter(recipesAdapter); 
   }
}

Finally, in OnCreateView change the construct to:

HttpRequest httpRequest = new HttpRequest(this);

correct the request initialization by calling the method:

httpRequest.sendGetRecipes(Recipes.RECIPES_URL);

and remove all the following rows until the "return view"

    
09.05.2017 / 13:16