我一直在研究如何实现Android的AsyncTask类。基本上,我希望它能够完成经典场景:在我进行网络呼叫时,简单地为无限加载轮设置动画。但是,在实践中,我遇到了一些问题,让它按照我想要的方式工作。
我的代码看起来像当前 :(在我想要的AsyncTask实现之前)
String result = timeConsumingNetworkCall(String someData, ArrayList stuff1);
doStuff(result);
String result = timeConsumingNetworkCall(String otherData, ArrayList stuff2);
doOtherStuff(result);
String result = timeConsumingNetworkCall(String dataAgain, ArrayList stuff3);
doYetEvenMore(result);
我希望能够重用我的AsyncTask调用来向其传递数据,它进行网络调用,然后返回我可以随意处理的数据,就像我上面那样。
现在 - 这完美无缺,当然除了没有加载,应用程序似乎“挂起”。来自AsyncTask。也许我还没有完全“得到它” - 但是如何返回AsyncTask的数据OUTSIDE以便doStuffToUI()
等可以使用它?
最终,如果我可以使用与此类似的AsyncTask,我会喜欢它:
String result = new PostToFile("function_name", keysAndValues).execute().getResult();
doStuff(result); // this shouldn't execute until the AsyncTask is done
我这样做了吗?这是应该如何/可以做到的?这是我下面的AsyncTask类,为简洁起见缩短了。
private class PostToFile extends AsyncTask<PostToFile, Void, Void>{
private String functionName;
private ArrayList<NameValuePair> postKeyValuePairs;
private String result = "";
public PostToFile(String function, ArrayList<NameValuePair> keyValuePairs){
functionName= function;
postKeyValuePairs = keyValuePairs;
}
@Override
protected void onPreExecute() {
progressDialog = ProgressDialog.show(BaseActivity.getInstance(), "Loading", "Please wait...", true, false);
}
@Override
protected Void doInBackground(PostToFile... params) {
ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair(FUNCTION_KEYWORD, functionName));
for (int i = 0; i < postKeyValuePairs.size(); i++) {
nameValuePairs.add(postKeyValuePairs.get(i));
}
try{
// ***do the POST magic.***
result = response.toString();
}
catch (Exception e){
// clean up my mess
}
return null;
}
private String getResult(){
return result; // can I use this somehow???
}
@Override
protected void onPostExecute(Void result) {
progressDialog.dismiss();
}
}
感谢任何帮助,非常感谢提前。如果需要,我很乐意澄清。
答案 0 :(得分:1)
doStuff(结果);在AsyncTask完成之前,这不应该执行
然后你需要使用AsyncTask.get(),如果有必要使Waits完成计算,然后检索它的结果。
因为调用AsyncTask.get()
冻结主UI线程直到doInBackground
执行未完成,所以你需要使用Thread来避免冻结UI和runOnUiThread
以便在AsyncTask执行后更新Ui元素完成。
示例: -
public void ThreaddoStuff(){
Thread th=new Thread(){
@Override
public void run(){
// start AsyncTask exection here
String result = new PostToFile("function_name",
keysAndValues).execute().get().getResult();
// now call doStuff by passing result
doStuff(result);
}
};
th.start();
}
答案 1 :(得分:1)
使用默认的onPostExecute实现创建可重用的异步任务,然后覆盖每次调用的默认实现:
public static class PostToFile extends AsyncTask<Void, Void, String> {
private String functionName;
private ArrayList<NameValuePair> postKeyValuePairs;
private String result = "";
public PostToFile(String function, ArrayList<NameValuePair> keyValuePairs){
functionName= function;
postKeyValuePairs = keyValuePairs;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
// show progress bar
}
@Override
protected String doInBackground(Void... arg0) {
// make request and get the result
return null; // return result
}
@Override
protected void onCancelled(String result) {
super.onCancelled(result);
// hide progress bar
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
// hide progress bar
}
}
执行您的异步任务:
new PostToFile(function, keyValuePairs) {
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result); // this will hide a progress bar
doStuff(result);
}
}.execute();
new PostToFile(otherFunction, otherKeyValuePairs) {
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result); // this will hide a progress bar
doOtherStuff(result);
}
}.execute();