本文翻译自:How to get the result of OnPostExecute() to main activity because AsyncTask is a separate class?
I have this two classes. 我有这两节课。 My main Activity and the one that extends the AsyncTask
, Now in my main Activity I need to get the result from the OnPostExecute()
in the AsyncTask
. 我的主要活动和扩展AsyncTask
活动,现在在我的主要活动中,我需要从AsyncTask
的OnPostExecute()
获取结果。 How can I pass or get the result to my main Activity? 如何将结果传递或获得主要活动?
Here is the sample codes. 这是示例代码。
My main Activity. 我的主要活动。
public class MainActivity extends Activity{
AasyncTask asyncTask = new AasyncTask();
@Override
public void onCreate(Bundle aBundle) {
super.onCreate(aBundle);
//Calling the AsyncTask class to start to execute.
asyncTask.execute(a.targetServer);
//Creating a TextView.
TextView displayUI = asyncTask.dataDisplay;
displayUI = new TextView(this);
this.setContentView(tTextView);
}
}
This is the AsyncTask class 这是AsyncTask类
public class AasyncTask extends AsyncTask<String, Void, String> {
TextView dataDisplay; //store the data
String soapAction = "http://sample.com"; //SOAPAction header line.
String targetServer = "https://sampletargeturl.com"; //Target Server.
//SOAP Request.
String soapRequest = "<sample XML request>";
@Override
protected String doInBackground(String... string) {
String responseStorage = null; //storage of the response
try {
//Uses URL and HttpURLConnection for server connection.
URL targetURL = new URL(targetServer);
HttpURLConnection httpCon = (HttpURLConnection) targetURL.openConnection();
httpCon.setDoOutput(true);
httpCon.setDoInput(true);
httpCon.setUseCaches(false);
httpCon.setChunkedStreamingMode(0);
//properties of SOAPAction header
httpCon.addRequestProperty("SOAPAction", soapAction);
httpCon.addRequestProperty("Content-Type", "text/xml; charset=utf-8");
httpCon.addRequestProperty("Content-Length", "" + soapRequest.length());
httpCon.setRequestMethod(HttpPost.METHOD_NAME);
//sending request to the server.
OutputStream outputStream = httpCon.getOutputStream();
Writer writer = new OutputStreamWriter(outputStream);
writer.write(soapRequest);
writer.flush();
writer.close();
//getting the response from the server
InputStream inputStream = httpCon.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
ByteArrayBuffer byteArrayBuffer = new ByteArrayBuffer(50);
int intResponse = httpCon.getResponseCode();
while ((intResponse = bufferedReader.read()) != -1) {
byteArrayBuffer.append(intResponse);
}
responseStorage = new String(byteArrayBuffer.toByteArray());
} catch (Exception aException) {
responseStorage = aException.getMessage();
}
return responseStorage;
}
protected void onPostExecute(String result) {
aTextView.setText(result);
}
}
#1楼
参考:https://stackoom.com/question/qlLg/由于AsyncTask是一个单独的类-如何使OnPostExecute-的结果进入主要活动
#2楼
You can call the get()
method of AsyncTask
(or the overloaded get(long, TimeUnit)
). 您可以调用AsyncTask
的get()
方法(或重载的get(long, TimeUnit)
)。 This method will block until the AsyncTask
has completed its work, at which point it will return you the Result
. 该方法将一直阻塞,直到AsyncTask
完成其工作为止,此时它将返回Result
。
It would be wise to be doing other work between the creation/start of your async task and calling the get
method, otherwise you aren't utilizing the async task very efficiently. 在创建/启动异步任务与调用get
方法之间进行其他工作是明智的,否则您将无法非常有效地利用异步任务。
#3楼
There are a few options: 有几种选择:
Nest the
AsyncTask
class within yourActivity
class. 将AsyncTask
类嵌套在Activity
类中。 Assuming you don't use the same task in multiple activities, this is the easiest way. 假设您没有在多个活动中使用同一任务,这是最简单的方法。 All your code stays the same, you just move the existing task class to be a nested class inside your activity's class. 您所有的代码保持不变,只需将现有任务类移动到活动类内的嵌套类即可。public class MyActivity extends Activity { // existing Activity code ... private class MyAsyncTask extends AsyncTask<String, Void, String> { // existing AsyncTask code ... } }
Create a custom constructor for your
AsyncTask
that takes a reference to yourActivity
. 为您的AsyncTask
创建一个自定义构造函数,该构造函数引用您的Activity
。 You would instantiate the task with something likenew MyAsyncTask(this).execute(param1, param2)
. 您将使用诸如new MyAsyncTask(this).execute(param1, param2)
类的实例化任务。public class MyAsyncTask extends AsyncTask<String, Void, String> { private Activity activity; public MyAsyncTask(Activity activity) { this.activity = activity; } // existing AsyncTask code ... }
#4楼
Create a static member in your Activity class. 在您的Activity类中创建一个静态成员。 Then assign the value during the onPostExecute
然后在onPostExecute
期间分配值
For example, if the result of your AsyncTask is a String, create a public static string in your Activity 例如,如果您的AsyncTask的结果是一个字符串,请在您的Activity中创建一个公共静态字符串
public static String dataFromAsyncTask;
Then, in the onPostExecute
of the AsyncTask, simply make a static call to your main class and set the value. 然后,在AsyncTask的onPostExecute
中,只需对主类进行静态调用并设置值即可。
MainActivity.dataFromAsyncTask = "result blah";
#5楼
Easy: 简单:
Create
interface
class, whereString output
is optional, or can be whatever variables you want to return. 创建interface
类,其中String output
是可选的,或者可以是您想要返回的任何变量。public interface AsyncResponse { void processFinish(String output); }
Go to your
AsyncTask
class, and declare interfaceAsyncResponse
as a field : 转到您的AsyncTask
类,并将接口AsyncResponse
声明为字段:public class MyAsyncTask extends AsyncTask<Void, Void, String> { public AsyncResponse delegate = null; @Override protected void onPostExecute(String result) { delegate.processFinish(result); } }
In your main Activity you need to
implements
interfaceAsyncResponse
. 在您的主要Activity中,您需要implements
AsyncResponse
接口。public class MainActivity implements AsyncResponse{ MyAsyncTask asyncTask =new MyAsyncTask(); @Override public void onCreate(Bundle savedInstanceState) { //this to set delegate/listener back to this class asyncTask.delegate = this; //execute the async task asyncTask.execute(); } //this override the implemented method from asyncTask @Override void processFinish(String output){ //Here you will receive the result fired from async class //of onPostExecute(result) method. } }
UPDATE 更新
I didn't know this is such a favourite to many of you. 我不知道这是你们中许多人的最爱。 So here's the simple and convenience way to use interface
. 因此,这是使用interface
简便方法。
still using same interface
. 仍然使用相同的interface
。 FYI, you may combine this into AsyncTask
class. 仅供参考,您可以将其合并到AsyncTask
类中。
in AsyncTask
class : 在AsyncTask
类中:
public class MyAsyncTask extends AsyncTask<Void, Void, String> {
// you may separate this or combined to caller class.
public interface AsyncResponse {
void processFinish(String output);
}
public AsyncResponse delegate = null;
public MyAsyncTask(AsyncResponse delegate){
this.delegate = delegate;
}
@Override
protected void onPostExecute(String result) {
delegate.processFinish(result);
}
}
do this in your Activity
class 在您的Activity
课中进行
public class MainActivity extends Activity {
MyAsyncTask asyncTask = new MyAsyncTask(new AsyncResponse(){
@Override
void processFinish(String output){
//Here you will receive the result fired from async class
//of onPostExecute(result) method.
}
}).execute();
}
Or, implementing the interface on the Activity again 或者,再次在Activity上实现接口
public class MainActivity extends Activity
implements AsyncResponse{
@Override
public void onCreate(Bundle savedInstanceState) {
//execute the async task
new MyAsyncTask(this).execute();
}
//this override the implemented method from AsyncResponse
@Override
void processFinish(String output){
//Here you will receive the result fired from async class
//of onPostExecute(result) method.
}
}
As you can see 2 solutions above, the first and third one, it needs to create method processFinish
, the other one, the method is inside the caller parameter. 如您所见,上面有2个解决方案,第一个和第三个,它需要创建方法processFinish
,另一个,该方法在调用者参数内部。 The third is more neat because there is no nested anonymous class. 第三个更整洁,因为没有嵌套的匿名类。 Hope this helps 希望这可以帮助
Tip : Change String output
, String response
, and String result
to different matching types in order to get different objects. 提示 :将String output
, String response
和String result
更改为不同的匹配类型,以获取不同的对象。
#6楼
in your Oncreate(): 在您的Oncreate()中:
` `
myTask.execute("url");
String result = "";
try {
result = myTask.get().toString();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}` }`