【问题标题】:Work in background thread stopping UI thread在后台线程中工作,停止 UI 线程
【发布时间】:2018-10-01 06:40:32
【问题描述】:

我正在后台线程中获取和处理一些 JSON 数据......即使这样我也可以在我的日志中看到警告说应用程序在 ht ui 线程中做了太多的工作。我不明白出了什么问题。

这是我的方法:

     private void getLists1() {
            busy =true;
            runOnUiThread(()->{
                listPD.show();
            });
            MyAsyncTask1 asyncTask1 = new MyAsyncTask1((String output) -> {
                if (!output.equals("failed")) {
                    runOnUiThread(()->{
                        listPD.setMessage("getting expense list");
                    });
                    JSONObject jsonObject = new JSONObject(output);
                    JSONArray array = jsonObject.getJSONArray("records_et");
                    int ii = array.length();
                    for (int i = 0; i < ii; i++) {
                        JSONObject jsonObject1 = array.getJSONObject(i);
                        String id = jsonObject1.getString("id");
                        String name1 = jsonObject1.getString("name");
                        int finalI = i;

                        listDB.insertItem(name1, id);

                    }
                    runOnUiThread(()->{
                        listPD.setMessage("expense list saved");
                    });

                }
            });
            asyncTask1.executeOnExecutor((AsyncTask.THREAD_POOL_EXECUTOR), "http://webservice");
            MyAsyncTask1 asyncTask2 = new MyAsyncTask1(output1 -> {
                if (!output1.equals("failed")) {
                    Log.i("response", "vendor " + output1);
                    runOnUiThread(()->{
                        listPD.setMessage("getting vendor list");
                    });
                    //vendor list
                    JSONObject jsonObject12 = new JSONObject(output1);
                    JSONArray array1 = jsonObject12.getJSONArray("records_vendor");
                    int ii1 = array1.length();

                    for (int i = 0; i < ii1; i++) {
                        JSONObject jsonObject1 = array1.getJSONObject(i);
                        String id = jsonObject1.getString("id");
                        String name1 = jsonObject1.getString("name");
                        int finalI = i;

                        listDB.insertVendorItem(name1, id);
                    }
                    runOnUiThread(()->{
                        listPD.setMessage("vendor list saved");
listPD.dismiss();
                    });

                }
            });
            asyncTask2.executeOnExecutor((AsyncTask.THREAD_POOL_EXECUTOR), "http://webservice");
    }

我这样调用方法;​​

new Thread(()->{
getLists1();
}).start();

listPD 是进度对话框...当我调用此函数时,应用程序开始滞后,这是我在这里所缺少的。

【问题讨论】:

  • 为什么你有一个线程开始 2 个异步任务?这真的很奇怪。发布您的 MyAsyncTask 类。问题可能就在那里。我认为您不了解 AsyncTasks,因为不需要创建线程来启动它们,而且您永远不会将 runOnUiThread 作为 AsyncTask 的最后一行——这就是 onPostExecute 的用途。
  • 我正在使用来自不同类的一个异步任务,并且我正在实现一个名为 onPostExecure 的接口,因此我可以重用代码。我还在允许并行执行异步任务的 ThreadPoolExecutor 上执行它。问题是后台工作正在影响ui线程。我刚刚注意到这段代码在我的模拟器中运行良好,但是在我的 1gb 内存的旧 HTC 上落后了,也许代码是正确的,只是 JSON 的巨大大小导致了问题......
  • 我将尝试使用 GSON 或 Jackson 以获得更好的性能。你知道如何使用两者中的任何一个来完成相同的操作吗?

标签: android json android-asynctask background-thread


【解决方案1】:

AsyncTask 类用于执行更新 UI(用户界面)的后台操作。我们主要将它用于不会影响主线程的短操作。

AsyncTask 类首先使用 execute() 方法执行。在第一步中,AsyncTask 调用 onPreExecute() 然后 onPreExecute() 调用 doInBackground() 用于后台进程,然后 doInBackground() 调用 onPostExecute() 方法来更新 UI。按照此语法使用 AsyncTask

Android 中 AsyncTask 的语法:

private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
protected Long doInBackground(URL... urls) {
    // code that will run in the background
    return ;
}

protected void onProgressUpdate(Integer... progress) {
    // receive progress updates from doInBackground
}

protected void onPostExecute(Long result) {
    // update the UI after background processes completes
}

}

从主线程执行 AsyncTask 类:

new DownloadFilesTask().execute(url1, url2, url3);

【讨论】:

  • 我正在使用来自不同类的一个异步任务,并且我正在实现一个名为 onPostExecure 的接口,因此我可以重用代码。我还在允许并行执行异步任务的 ThreadPoolExecutor 上执行它。问题是后台工作正在影响ui线程。我刚刚注意到这段代码在我的模拟器中完美运行,但是在我的旧 HTC 上落后了 1gb 的内存,也许代码是正确的,只是 JSON 的巨大大小导致了问题......
  • 我将尝试使用 GSON 或 Jackson 以获得更好的性能。你知道如何使用两者中的任何一个来完成相同的操作吗?
  • 在构造函数中传递 GSON 数据:public DownloadFilesTask(GSON data){} 并从您想要的任何其他类调用 execute():new DownloadFilesTask(GsonData).execute(url1, url2, url3);
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-21
  • 1970-01-01
  • 2020-02-02
相关资源
最近更新 更多