Why is this skipping the onResponse method?

2019-09-16 04:36发布

问题:

I want to get data from JSON and then return it in an array, but the array always return with null, because my program won't go into the onResponse method.

I want to show this data in a RecyclerView. At first it worked but now it won't work I don't know why...

private SzabadEuMusorok[] getSzabadEuMusoroks(){
    if (isNetworkAvaible()){
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder().url("validurl").build();

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

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                try {
                    String jsonData = response.body().string();
                    Log.v("JSONDATA", jsonData);
                    if(response.isSuccessful()){
                        JSONArray jsonArray = new JSONArray(jsonData);

                        mSzabadEuMusoroks = new SzabadEuMusorok[jsonArray.length()];

                        for (int i = 0; i < jsonArray.length(); i++){
                            JSONObject jsonObject = jsonArray.getJSONObject(i);
                            SzabadEuMusorok szabadEuMusorok = new SzabadEuMusorok();
                            JSONArray elementTexts = jsonObject.getJSONArray("element_texts");

                            JSONObject titleObject = elementTexts.getJSONObject(0);
                            szabadEuMusorok.setTitile(titleObject.getString("text"));

                            JSONObject subjectObject = elementTexts.getJSONObject(3);
                            szabadEuMusorok.setSubject(subjectObject.getString("text"));

                            JSONObject mainObject = jsonObject.getJSONObject("files");
                            szabadEuMusorok.setVideoURL(mainObject.getString("url"));

                            mSzabadEuMusoroks[i] = szabadEuMusorok;
                        }
                    }
                } catch (JSONException e) {
                    Log.e("JSONEXCEPTION", "Exception caught: ", e);
                }
            }
        });
    }
    else{
        Toast.makeText(this, R.string.network_unavaible_message, Toast.LENGTH_LONG).show();
    }
    return mSzabadEuMusoroks;

回答1:

Your code is wrong in the logical sense. Because the call to web service is asynchronous, so when you uses "return", the array is empty, when your data is in the result doesn't matter because you already loaded the RecyclerView. The solution will be that you implement a callback function or use notifydatasetchanged in the RecyclerView.

Check the links.

Using callbacks in android

Using notifydatasetchanged

---------- notifydatasetchanged ----------

for (int i = 0; i < jsonArray.length(); i++){
  JSONObject jsonObject = jsonArray.getJSONObject(i);
  SzabadEuMusorok szabadEuMusorok = new SzabadEuMusorok();
  JSONArray elementTexts = jsonObject.getJSONArray("element_texts");

  JSONObject titleObject = elementTexts.getJSONObject(0);
  szabadEuMusorok.setTitile(titleObject.getString("text"));

  JSONObject subjectObject = elementTexts.getJSONObject(3);
  szabadEuMusorok.setSubject(subjectObject.getString("text"));

  JSONObject mainObject = jsonObject.getJSONObject("files");
  szabadEuMusorok.setVideoURL(mainObject.getString("url"));

  mSzabadEuMusoroks[i] = szabadEuMusorok;
}
//LINE ADDED-----------------------------------------------------
yourAdapterInTheRecyclerView.notifyDataSetChanged();
//LINE ADDED-----------------------------------------------------