如果我将AsynkTask类中给出的结果彼此接受:
Register.java:
public void onClick(View v) {
LoadFermate backgroundFermate = new LoadFermate(Register.this);
ArrayList<HashMap<String, String>> fermate;
try{
fermate = backgroundFermate.execute().get();
for (HashMap<String, String> fermata:fermate){
Toast.makeText(Register.this , fermata.get("Nome"), Toast.LENGTH_SHORT).show();
}
}catch (InterruptedException e){
e.printStackTrace();
}catch (ExecutionException e){
e.printStackTrace();
}
}
未显示ProgressDialog。如果我在onPostExecute
方法中执行所有这些操作,则会显示。怎么可能?
我学会了从that question中获取其他课程价值的方法。
这里我发布了使用ProgressDialog的类:
LoadingFermate.java:
package com.PacchettoPrincipale.app;
import [...]
public class LoadFermate extends AsyncTask<Void, Void, ArrayList<HashMap<String, String>>> {
private Context context;
public LoadFermate(Context context){
this.context = context;
}
private ProgressDialog pDialog;
private JSONArray mComments = null;
private ArrayList<HashMap<String, String>> mCommentList;
//testing on Emulator:
private static final String DOWNLOAD_FERMATE_URL = "http://10.0.2.2/PrimaAppAndroid/fermate.php";
//JSON IDS:
private static final String TAG_COD = "CodFermata";
private static final String TAG_POSTS = "posts";
private static final String TAG_NOME = "Nome";
@Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(context); //HERE I START THE PDIALOG, and in the onPostExecute method I dismiss it
pDialog.setMessage("Download fermate...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(true);
pDialog.show();
}
@Override
protected ArrayList<HashMap<String, String>> doInBackground(Void... voids) {
updateJSONData();
return mCommentList;
}
@Override
protected void onPostExecute(ArrayList<HashMap<String, String>> hashMaps) {
super.onPostExecute(hashMaps);
pDialog.dismiss();
}
private void updateJSONData() {
mCommentList = new ArrayList<HashMap<String, String>>();
JSONParser jParser = new JSONParser();
JSONObject json = jParser.getJSONFromUrl(DOWNLOAD_FERMATE_URL);
try {
mComments = json.getJSONArray(TAG_POSTS);
for (int i = 0; i < mComments.length(); i++) {
JSONObject c = mComments.getJSONObject(i);
int CodFermata = c.getInt(TAG_COD);
String Nome = c.getString(TAG_NOME);
HashMap<String, String> map = new HashMap<String, String>();
map.put(TAG_COD, String.valueOf(CodFermata));
map.put(TAG_NOME, Nome);
mCommentList.add(map);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
答案 0 :(得分:2)
这是因为在您等待任务完成时,您的应用程序的UI线程被阻止了。您的程序在此行被阻止:
ermate = backgroundFermate.execute()。get();
文档说“get():等待计算完成所需,然后检索其结果。” (你可以在这里阅读:http://developer.android.com/reference/android/os/AsyncTask.html#get())
在Android中,多个线程无法操纵UI元素(例如进度对话框)。 (这意味着你不能调用它们的任何方法,否则你最终会遇到异常。)它们只能由它们创建的线程来操纵。该线程是应用程序的主线程(或UI线程,换句话说)。
但是我们需要在单独的线程上工作,并且仍然想要更新UI!
这个问题可以通过几种方式解决。通过使用Handler和Runnables,但有时可能很复杂。 AsyncTask的概念是做这项工作而不是你。在单独的线程上执行任务之前,在UI线程上执行OnPreExecute(),并且还在主线程上执行onPostExecute()。
如果你知道这件事,我很抱歉。回到你的问题: 因为你通过调用AsyncTask上的get()来阻止UI线程,所以onPreExecute()和onPostExecute()无法在UI线程上运行!它们被发布到主线程,但只有在主线程完成它正在做的事情之后它们才会运行。那是在get()返回之后。然后会立即显示并关闭一个对话框,这就是为什么你看不到它。
不要以这种方式等待结果。在onPostExecute()中处理结果,因为它是为此目的而设计的。
答案 1 :(得分:1)
this is just a test, later I'll need this HashMap in the calling class for making a graph(fermate are the liefs). Can I retrieve it in another way?
marcin_j回答了get()
部分。调用get()
会阻止ui线程使其不再异步。
是的,有办法。您可以使用界面作为活动的回调。
通过黑带检查答案
How do I return a boolean from AsyncTask?
而不是在你的情况下布尔其HashMap。
您还可以将Asynctask作为活动的内部类