Вторая функция выполняется до полного выполнения первой функции - PullRequest
0 голосов
/ 03 мая 2019

У меня есть две функции fetchData () и setDataUI (), в fetchData () я отправляю запрос и сохраняю ответ. В функции setDataUI () я устанавливаю адаптер для привязки данных.

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_image_gallery);

        recyclerView = (RecyclerView) findViewById(R.id.image_recycler_view);
        data_list = new ArrayList<>();

        fetchData2(1);
}

fetchData2 () для извлечения данных с сервера.

public void fetchData2(final int next){
        String url = Constants.URL+"image/gallery?page="+next;
        Log.d(TAG,"Data2 Url-->"+url);
        StringRequest stringRequest = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                try {
                    Log.d(TAG, "Response-->" + response);
                    JSONObject jsonObject = new JSONObject(response);
                    JSONArray jsonArray = jsonObject.getJSONArray("media");
                    Log.d(TAG, "Media Array-->" + jsonArray);
                    for (int i = 0; i < jsonArray.length(); i++) {
                        JSONObject jsonObject1 = jsonArray.getJSONObject(i);

                        ImageGallery imageGallery = new ImageGallery(
                                jsonObject1.getString("file"),
                                jsonObject1.getString("description"),
                                jsonObject.getInt("next"));

                        data_list.add(imageGallery);

                        Log.d(TAG, "Data List in AsyncTask-->" + data_list);
                        setDataUI();

                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Toast.makeText(ActivityImageGallery.this, "Server Error!!!!", Toast.LENGTH_SHORT).show();
            }
        });

        RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());
        requestQueue.add(stringRequest);
    }

затем в setDataUI ()

 private void setDataToUI() {
        gridLayoutManager = new GridLayoutManager(this,1);

        recyclerView.setLayoutManager(gridLayoutManager);

        Log.d(TAG,"Data_List-->"+data_list);

        adapter = new AdapterImageGallery(this, data_list);
        recyclerView.setAdapter(adapter);

        recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {

            @Override
            public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                if (gridLayoutManager.findLastCompletelyVisibleItemPosition() == data_list.size()-1){
                    fetchData2(data_list.get(data_list.size()-1).getNext());
                }
            }
        });
    }

Ожидаемый результат: Функция setDataUI () должна запускаться только тогда, когда fetchData2 () полностью завершает выполнение. Итак, data_list в setDataUI () будет иметь значения, которые инициализированы в fetchData2 ().

Фактический результат: в настоящее время setDataUI () начинает выполнение до того, как fetchData2 () завершит свое выполнение, в результате чего data_list будет пустым в setDataUI ().

Я получаю правильный ответ от сервера, но после выполнения setDataUI ().

Ответы [ 3 ]

1 голос
/ 03 мая 2019

Что вам нужно сделать, это просто изменить, как показано ниже в вашем методе ответа,

            @Override
            public void onResponse(String response) {
                try {
                    if(response.isSuccessful){
                    Log.d(TAG, "Response-->" + response);
                    JSONObject jsonObject = new JSONObject(response);
                    JSONArray jsonArray = jsonObject.getJSONArray("media");
                    Log.d(TAG, "Media Array-->" + jsonArray);
                    for (int i = 0; i < jsonArray.length(); i++) {
                        JSONObject jsonObject1 = jsonArray.getJSONObject(i);

                        ImageGallery imageGallery = new ImageGallery(
                                jsonObject1.getString("file"),
                                jsonObject1.getString("description"),
                                jsonObject.getInt("next"));

                        data_list.add(imageGallery);

                        Log.d(TAG, "Data List in AsyncTask-->" + data_list);
                        }
                       setDataToUI();
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }

-Put setDataToUI (); вызов метода после завершения цикла for в onresponse. -Также, ваш второй метод выполняется перед вашим первым методом, потому что ваш первый метод асинхронный (то есть работает в другом потоке. Он не выполняется в основном потоке или потоке пользовательского интерфейса).

0 голосов
/ 03 мая 2019

Это потому, что в вашей fetchData() асинхронная задача выполняется в фоновом режиме, и вы не можете предсказать, сколько времени это займет. Поэтому вместо вызова setDataToUI() после fetchData2() функции вы можете просто вызвать ее внутри ответа функции fetchData2(). Вы можете редактировать это в функции fetchData2

data_list.add(imageGallery); Log.d(TAG, "Data List in AsyncTask-->" + data_list); setDataToUI()

0 голосов
/ 03 мая 2019

Запросы залпов являются асинхронными. Таким образом, вы должны позвонить своему setDataToUI с обратного вызова:

 StringRequest stringRequest = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                 // all your code

                 runOnUiThread(new Runnable() {
                         @Override
                         public void run() {
                               setDataToUI();
                         }
                   }
        } 
...