【问题标题】:Showing JSON API data in UI在 UI 中显示 JSON API 数据
【发布时间】:2020-07-22 09:48:22
【问题描述】:

我正在尝试显示我的请求的结果,但它在最后执行了请求。 你可以看到日志。

我尝试了 3 种不同的方法

1 - 创建一个扩展 BaseAdapter 的子类 2 - 创建一个 RecycleView.AdapterView 3 - AsyncTask(如果正确,则在“渲染 UI”之前运行请求)

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

【问题讨论】:

  • 您不需要 AsyncTask 进行 Volley 调用,因为请求是在单独的工作线程中处理的,而不是在 UI 线程上
  • 好的,那么我怎样才能将请求中的数据显示到 UI,从我发现需要先完成请求以便我可以在 UI 中呈现数据,如果正确的话我可以这样做吗?
  • 我在下面添加了解决方案。

标签: android json api cardview


【解决方案1】:

问题:您的方法的主要问题是您在另一个异步调用中进行异步调用并期望同步结果。这就是为什么结果是空的,因为内部异步调用还没有完成。

解决方案:您可以通过完全删除 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");

                }
            }
 }

注意:您直接从响应中填充 UI 的方式也不是很有效。您可以使用带有Gson library 的模型类进行解析。

干杯:)

【讨论】:

  • 我应该补充一点,使用 Retrofit 代替异步任务也会很好。
猜你喜欢
  • 2017-01-17
  • 1970-01-01
  • 2023-03-25
  • 1970-01-01
  • 1970-01-01
  • 2021-06-25
  • 1970-01-01
  • 1970-01-01
  • 2019-02-06
相关资源
最近更新 更多