AsyncTask 未到达 onPostExecute() - "The application may be doing too much in its main thread"



我有一个片段,我想在其中解析一个JSON并创建一个具有其一些属性的ArrayList,然后将ArrayList的数据放入微调器。但是,我不知道我是否正在执行AsyncTask。每次我尝试一种新方法来解析片段活动中的 URL 中的 JSON 时,应用程序都会崩溃并显示"不幸的是,应用程序已停止"消息,或者微调器保持为空。我用日志验证了我从未到达AsyncTask上的onPostExecute()方法。问题:- 我做错了什么?- 我应该使用AsyncTask吗?

我的代码:

 private class LoadResources extends AsyncTask<String, Void, String> {
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            Log.v(TAG, "pre-execute");
        }
        // Call after onPreExecute method
        @Override
        protected String doInBackground(String... urls) {
            Log.v(TAG, "background");
            Log.v(TAG, urls[0]);
            for (int i = 0; i < 5; i++) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    Thread.interrupted();
                }
            }
            try {
                URL u = new URL(urls[0]);
                BufferedReader in = new BufferedReader(new InputStreamReader(u.openStream(), Charset.forName("UTF-8")));
                StringBuilder sb = new StringBuilder();
                String line;
                while ((line = in.readLine()) != null) {
                    sb.append(line);
                }
// the above parsing works, I've tested
                JsonParser parser = new JsonParser();
                JsonElement elem = parser.parse(sb.toString());
                JsonArray array = elem.getAsJsonArray();
                    for (int i = 0; i < array.size(); i++) {
                        JsonElement elem1 = array.get(i);
                        JsonArray tmpArr = elem1.getAsJsonArray();
                        for (JsonElement elem2 : tmpArr) {
elem2.getAsJsonObject().getAsJsonPrimitive().getAsString());
                           myArrayList.add(elem2.getAsJsonObject().getAsJsonPrimitive("name").toString());
                return urls[0];
            }
            protected void onPostExecute(String params) {
Log.v(TAG, params);
            }
        }

在onCreateView上:

LoadResources loader = new LoadResources();
            loader.execute("http://localhost:5000/avalidpath);
            text = (AutoCompleteTextView) rootView.findViewById(R.id.nomeAluno);
            final ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity().getApplicationContext(),
                    android.R.layout.simple_spinner_dropdown_item, myArrayList);
            text.setAdapter(adapter);
            text.setThreshold(3);

现在,当我滑动到此片段时,该应用程序停止工作。提前谢谢,伙计们。

实际上,

您应该在doInBckground方法中完成繁重的工作。

onPostExecute(Result),在后台计算完成后在 UI 线程上调用。后台计算的结果作为参数传递给此步骤。文档在这里

编辑:

class LoadResources extends AsyncTask<String, Void, ArrayList<String>> {
     Context context;
     public LoadResources(Context context) {
       this.context = context;
     }
     @Override
     protected String doInBackground(String... urls) {
        ...
        return myArrayList;
     }
     protected void onPostExecute(ArrayList<String> params) {
       ((YourActivity)context).setMyAdapter(params);
     }
}

在您的活动(片段或其他内容)中:

public void setMyAdapter(ArrayList<String> params) {
   final ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity().getApplicationContext(),
                android.R.layout.simple_spinner_dropdown_item, myArrayList);
   text.setAdapter(adapter);
}

onPostExecute 是在 UI 线程上完成的。 你在这方面有太多的工作。 所有不直接影响UI元素的事情都应该在doInBackground中完成。 现在你的doInBackground什么都不做。

将整个代码从onPostExecute移动到doInBackground。您可以使用publishProgress(...);onProgressUpdate将项目添加到列表中。或者在 AsyncTask 中创建本地列表,并在 onPostExecute 中将所有项目添加到全局列表中

相关内容

最新更新