Отображение JSON данных API в пользовательском интерфейсе - PullRequest
0 голосов
/ 09 апреля 2020

Я пытаюсь показать результат моего запроса, но он выполняет запрос в конце. Вы можете просмотреть журналы.

Я пробовал 3 разных способа

1 - Создать подкласс, расширяющий BaseAdapter 2 - Создать RecycleView.AdapterView 3 - AsyncTask (для запуска запроса перед "рендерингом Пользовательский интерфейс ", если это правильно)

public class MainActivity extends AppCompatActivity {

JSONArray result = new JSONArray();

TextView name, phone, location;

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

    name = findViewById(R.id.name);
    phone = findViewById(R.id.phone);
    location = findViewById(R.id.location);
    Log.i("MainActivity","finished with TextViews");

    new MyTask().execute(url);
}

private class MyTask extends AsyncTask<String, Void, JSONArray> {

    @Override
    protected JSONArray doInBackground(String... params) {

        Log.i("MainActivity","starting with doInBackground");
        RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());
        String url = params[0];
        JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(Request.Method.GET, url, null,
                new Response.Listener<JSONArray>() {
                    @Override
                    public void onResponse(JSONArray response) {
                        result = response;

                        Log.i("MainActivity",result.toString());
                    }
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {

                        error.printStackTrace();
                        result.put(error.toString());

                    }
                }
        ) {
            @Override
            public Map<String, String> getHeaders() throws AuthFailureError {
                Map<String, String> token = new HashMap<>();
                token.put("Authorization", "Token *************");
                return token;
            }
        };
        requestQueue.add(jsonArrayRequest);
        Log.i("MainActivity", "finished with doInBackground");
        return result;
    }

    @Override
    protected void onPostExecute(JSONArray result) {
        super.onPostExecute(result);
        Log.i("MainActivity","stating with onPostExecute");
        // do something with result

        for(int i = 0; i<result.length(); i++){
            try {
                name.setText(new JSONObject(result.get(i).toString()).get("seller_name").toString());
                phone.setText(new JSONObject(result.get(i).toString()).get("seller_phone").toString());
                location.setText(new JSONObject(result.get(i).toString()).get("seller_location").toString());
            }catch(JSONException e){
                e.printStackTrace();
                name.setText("Error");
                phone.setText("Error");
                location.setText("Error");

            }
        }

        Log.i("MainActivity","finished with onPostExecute");
    }
}

public JSONArray doSomeWork(String url_) {

    Log.i("MainActivity","starting with doSomeWork");

    return result;
}}

Журналы:

MainActivity: завершено с TextViews

MainActivity: начинается с doInBackground

MainActivity: завершено с doInBackground

MainActivity: указание с помощью onPostExecute

MainActivity: завершение с помощью onPostExecute

MainActivity: данные, возвращаемые методом onResponse - JSON

1 Ответ

0 голосов
/ 09 апреля 2020

Проблема: Основная проблема вашего подхода заключается в том, что вы делаете асинхронный вызов внутри другого асинхронного вызова и ожидаете синхронного результата. Вот почему результат пуст, потому что внутренний асинхронный вызов еще не завершен.

Решение: Вы можете решить эту проблему, удалив AsyncTask в целом, так как Volley по умолчанию выполняется в отдельном рабочем потоке.

Вы можете сделать что-то вроде этого

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

        name = findViewById(R.id.name);
        phone = findViewById(R.id.phone);
        location = findViewById(R.id.location);
        Log.i("MainActivity","finished with TextViews");

        doSomeWork(url);
    }


    private void doSomeWork(String url) {

        Log.i("MainActivity","starting with doSomeWork");

        RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());
        JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(Request.Method.GET, url, null,
                new Response.Listener<JSONArray>() {
                    @Override
                    public void onResponse(JSONArray response) {

                        renderUI(response);
                        Log.i("MainActivity",result.toString());
                    }
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {

                        error.printStackTrace();

                        result.put(error.toString());
                        renderUI(result);

                    }
                }
        ) {
            @Override
            public Map<String, String> getHeaders() throws AuthFailureError {
                Map<String, String> token = new HashMap<>();
                token.put("Authorization", "Token *************");
                return token;
            }
        };
        requestQueue.add(jsonArrayRequest);
    }

 private void renderUI(JSONArray result) {

         for(int i = 0; i<result.length(); i++){
                try {
                    name.setText(new JSONObject(result.get(i).toString()).get("seller_name").toString());
                    phone.setText(new JSONObject(result.get(i).toString()).get("seller_phone").toString());
                    location.setText(new JSONObject(result.get(i).toString()).get("seller_location").toString());
                }catch(JSONException e){
                    e.printStackTrace();
                    name.setText("Error");
                    phone.setText("Error");
                    location.setText("Error");

                }
            }
 }

Примечание: Кроме того, способ заполнения интерфейса непосредственно из ответа не очень эффективен. Для анализа можно использовать класс модели с библиотекой Gson .

Приветствия:)

...