问题
I have been looking at how to implement Android's AsyncTask class for some time now. Basically, I want it to do the classic scenario: simply animate an indefinite loading wheel while I make a network call. However, in practice I'm having some issues getting this to work the way I want.
I have code that looks like this currently: (before my desired AsyncTask implementation)
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);
I want to be able to reuse my AsyncTask call to pass data to it, it makes a network call, and then returns me data that I can then process as I wish, like I do above.
Now - this works perfect, except of course the app appears to "hang" with no loading. In comes AsyncTask. Maybe I just don't quite "get it" yet - but how do I return data OUTSIDE of the AsyncTask so that doStuffToUI()
etc can use it?
Ultimately, I'd like it if I could use the AsyncTask similar to this:
String result = new PostToFile("function_name", keysAndValues).execute().getResult();
doStuff(result); // this shouldn't execute until the AsyncTask is done
Am I going about this right? Is this how it should be/can be done? Here's my AsyncTask class below, shortened for brevity.
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();
}
}
Any help is appreciated, thanks a lot in advance. I'm happy to clarify if needed.
回答1:
doStuff(result); this shouldn't execute until the AsyncTask is done
then you will need to use AsyncTask.get() which make Waits if necessary for the computation to complete, and then retrieves its result.
because calling of AsyncTask.get()
freeze main UI thread until doInBackground
execution is not complete then u will need to use Thread to avoid freezing of UI and runOnUiThread
for updating Ui elements after AsyncTask execution complete.
Example :-
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();
}
回答2:
Make a reusable async task with default onPostExecute implementation and then override default implementation for every call:
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
}
}
Execute your async task:
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();
来源:https://stackoverflow.com/questions/15153919/androids-asynctask-multiple-params-returning-values-waiting