如何获得OnPostExecute()的主要活动的结果,因为AsyncTask是一个单独的类?

我有这两个class。 我的主要活动和扩展AsyncTask ,现在在我的主要活动我需要从AsyncTaskOnPostExecute()的结果。 我怎样才能将结果传递给我的主要活动?

这里是示例代码。

我的主要活动。

 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); } } 

这是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. 创buildinterface类,其中String output是可选的,或者可以是任何想要返回的variables。

     public interface AsyncResponse { void processFinish(String output); } 
  2. 转到您的AsyncTask类,并将AsyncResponse接口声明为一个字段:

     public class MyAsyncTask extends AsyncTask{ public AsyncResponse delegate = null; @Override protected void onPostExecute(String result) { delegate.processFinish(result); } } 
  3. 在您的主要活动中,您需要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

我不知道这是你们中许多人的最爱。 所以这里是使用interface的简单和方便的方法。

仍然使用相同的interface 。 仅供参考,您可以将其组合成AsyncTask类。

AsyncTask类中:

 public class MyAsyncTask extends AsyncTask{ // 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); } } 

在你的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(); } 

或者,再次在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. } } 

正如你可以看到上面的两个解决scheme,第一个和第三个,它需要创build方法processFinish ,另一个,方法是在调用者参数内。 第三个更整洁,因为没有嵌套的匿名类。 希望这可以帮助

有几个选项:

  • Activity类中嵌套AsyncTask类。 假设你在多个活动中不使用相同的任务,这是最简单的方法。 你所有的代码都保持不变,只要将现有的任务类移动到活动类中的嵌套类即可。

     public class MyActivity extends Activity { // existing Activity code ... private class MyAsyncTask extends AsyncTask<String, Void, String> { // existing AsyncTask code ... } } 
  • 为您的AsyncTask创build一个自定义的构造函数,以引用您的Activity 。 你会用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 ... } 

你可以在你的Main类中尝试这个代码。 这对我有效,但我已经用其他方式实现了方法

 try { String receivedData = new AsyncTask().execute("http://yourdomain.com/yourscript.php").get(); } catch (ExecutionException | InterruptedException ei) { ei.printStackTrace(); } 

我觉得下面的方法很简单。

我已经声明了一个callback接口

 public interface AsyncResponse { void processFinish(Object output); } 

然后创build用于响应所有types的并行请求的asynchronous任务

  public class MyAsyncTask extends AsyncTask<Object, Object, Object> { public AsyncResponse delegate = null;//Call back interface public MyAsyncTask(AsyncResponse asyncResponse) { delegate = asyncResponse;//Assigning call back interfacethrough constructor } @Override protected Object doInBackground(Object... params) { //My Background tasks are written here return {resutl Object} } @Override protected void onPostExecute(Object result) { delegate.processFinish(result); } } 

然后在Activity类中单击button时调用asynchronous任务。

 public class MainActivity extends Activity{ @Override public void onCreate(Bundle savedInstanceState) { Button mbtnPress = (Button) findViewById(R.id.btnPress); mbtnPress.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { MyAsyncTask asyncTask =new MyAsyncTask(new AsyncResponse() { @Override public void processFinish(Object output) { Log.d("Response From Asynchronous task:", (String) output); mbtnPress.setText((String) output); } }); asyncTask.execute(new Object[] { "Your request to aynchronous task class is giving here.." }); } }); } } 

谢谢

你可以做几行,只要在调用AsyncTask的时候重写onPostExecute即可。 这里是你的一个例子:

 new AasyncTask() { @Override public void onPostExecute(String result) { // do whatever you want with result } }.execute(a.targetServer); 

我希望它帮助你,快乐codding 🙂

在你的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(); 

}`

嗨,你可以做这样的事情:

  1. 创build实现AsyncTask的类

     // TASK public class SomeClass extends AsyncTask<Void, Void, String>> { private OnTaskExecutionFinished _task_finished_event; public interface OnTaskExecutionFinished { public void OnTaskFihishedEvent(String Reslut); } public void setOnTaskFinishedEvent(OnTaskExecutionFinished _event) { if(_event != null) { this._task_finished_event = _event; } } @Override protected void onPreExecute() { super.onPreExecute(); } @Override protected String doInBackground(Void... params) { // do your background task here ... return "Done!"; } @Override protected void onPostExecute(String result) { super.onPostExecute(result); if(this._task_finished_event != null) { this._task_finished_event.OnTaskFihishedEvent(result); } else { Log.d("SomeClass", "task_finished even is null"); } } } 
  2. 添加主要活动

     // MAIN ACTIVITY public class MyActivity extends ListActivity { ... SomeClass _some_class = new SomeClass(); _someclass.setOnTaskFinishedEvent(new _some_class.OnTaskExecutionFinished() { @Override public void OnTaskFihishedEvent(String result) { Toast.makeText(getApplicationContext(), "Phony thread finished: " + result, Toast.LENGTH_SHORT).show(); } }); _some_class.execute(); ... } 

你可以编写你自己的监听器。 和HelmiB的回答一样,但看起来更自然:

创build监听器接口:

 public interface myAsyncTaskCompletedListener { void onMyAsynTaskCompleted(int responseCode, String result); } 

然后编写你的asynchronous任务:

 public class myAsyncTask extends AsyncTask<String, Void, String> { private myAsyncTaskCompletedListener listener; private int responseCode = 0; public myAsyncTask() { } public myAsyncTask(myAsyncTaskCompletedListener listener, int responseCode) { this.listener = listener; this.responseCode = responseCode; } @Override protected void onPreExecute() { super.onPreExecute(); } @Override protected String doInBackground(String... params) { String result; String param = (params.length == 0) ? null : params[0]; if (param != null) { // Do some background jobs, like httprequest... return result; } return null; } @Override protected void onPostExecute(String finalResult) { super.onPostExecute(finalResult); if (!isCancelled()) { if (listener != null) { listener.onMyAsynTaskCompleted(responseCode, finalResult); } } } } 

最后在活动中实现监听器:

 public class MainActivity extends AppCompatActivity implements myAsyncTaskCompletedListener { @Override public void onMyAsynTaskCompleted(int responseCode, String result) { switch (responseCode) { case TASK_CODE_ONE: // Do something for CODE_ONE break; case TASK_CODE_TWO: // Do something for CODE_TWO break; default: // Show some error code } } 

这就是你可以如何调用asyncTask:

  protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Some other codes... new myAsyncTask(this,TASK_CODE_ONE).execute("Data for background job"); // And some another codes... } 

你可以调用AsyncTaskget()方法(或重载get(long, TimeUnit) )。 这个方法会阻塞,直到AsyncTask完成它的工作,在这一点上它将返回Result

在创build/开始asynchronous任务和调用get方法之间做其他工作是明智的,否则你不能非常有效地利用asynchronous任务。

在Activity类中创build一个静态成员。 然后在onPostExecute过程中onPostExecute

例如,如果您的AsyncTask的结果是一个string,请在您的活动中创build一个公共静态string

public static String dataFromAsyncTask;

然后,在AsyncTask的onPostExecute中,只需对您的主类进行静态调用并设置该值即可。

MainActivity.dataFromAsyncTask = "result blah";

为什么人们这么难

这应该是足够的。

不要在asynchronous任务上实现onPostExecute,而是在Activity上实现它:

 public class MainActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { //execute the async task MyAsyncTask task = new MyAsyncTask(){ protected void onPostExecute(String result) { //Do your thing } } task.execute("Param"); } } 

这个答案可能会迟到,但是我想提一些事情,当你的Activity依赖于AsyncTask 。 这将有助于防止崩溃和内存pipe理。 正如在上面的答案中已经提到的那样,我们也使用interface表示callback。 他们将作为一个告密者,但从来没有发送Activity 强烈的参考或interface在这些情况下总是使用引用。

请参阅下面的屏幕截图,了解如何导致问题。

在这里输入图像描述

正如你所看到的,如果我们用强大的引用来启动AsyncTask ,那么不能保证我们的Activity / Fragment在我们获取数据之前是活着的,所以在这种情况下使用WeakReference会更好,这也将有助于内存pipe理我们永远不会持有我们的Activity的强烈的参考,那么它将失败后有资格进行垃圾收集。

检查下面的代码片断,找出如何使用真棒WeakReference –

MyTaskInformer.java将作为告密者的接口。

 public interface MyTaskInformer { void onTaskDone(String output); } 

MySmallAsyncTask.java AsyncTask做长时间运行的任务,它将使用WeakReference

 public class MySmallAsyncTask extends AsyncTask<String, Void, String> { // ***** Hold weak reference ***** private WeakReference<MyTaskInformer> mCallBack; public MySmallAsyncTask(MyTaskInformer callback) { this.mCallBack = new WeakReference<>(callback); } @Override protected String doInBackground(String... params) { // Here do whatever your task is like reading/writing file // or read data from your server or any other heavy task // Let us suppose here you get response, just return it final String output = "Any out, mine is just demo output"; // Return it from here to post execute return output; } @Override protected void onPostExecute(String s) { super.onPostExecute(s); // Here you can't guarantee that Activity/Fragment is alive who started this AsyncTask // Make sure your caller is active final MyTaskInformer callBack = mCallBack.get(); if(callBack != null) { callBack.onTaskDone(s); } } } 

MainActivity.java这个类用于在这个类上启动我的AsyncTask实现interfaceoverride这个必需的方法。

 public class MainActivity extends Activity implements MyTaskInformer { private TextView mMyTextView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mMyTextView = (TextView) findViewById(R.id.tv_text_view); // Start your AsyncTask and pass reference of MyTaskInformer in constructor new MySmallAsyncTask(this).execute(); } @Override public void onTaskDone(String output) { // Here you will receive output only if your Activity is alive. // no need to add checks like if(!isFinishing()) mMyTextView.setText(output); } } 

我通过使用线程和处理程序/消息使它工作。 步骤如下:声明进度对话框

 ProgressDialog loadingdialog; 

操作完成后,创build一个closures对话框的function。

  private Handler handler = new Handler() { @Override public void handleMessage(Message msg) { loadingdialog.dismiss(); } }; 

编码您的执行细节:

  public void startUpload(String filepath) { loadingdialog = ProgressDialog.show(MainActivity.this, "Uploading", "Uploading Please Wait", true); final String _path = filepath; new Thread() { public void run() { try { UploadFile(_path, getHostName(), getPortNo()); handler.sendEmptyMessage(0); } catch (Exception e) { Log.e("threadmessage", e.getMessage()); } } }.start(); } 

例如,不需要使用接口,因为您无法获取其外部返回值并将其分配给任何variables。 所有你需要的是get ()方法,它在doInBackground ()结束它的工作时等待,监听onPostExecute ()结果并返回它:

 String result = new myAsyncTask ().execute ().get (); 

现在你可以在你想要的地方使用resultvariables。 这个值的数据types与onPostExecute ()onPostExecute () 。 但是你不能在另一个AsuncTask的AsyncTask中使用它,因为你会得到一个无限循环。 但是我不能想象当你需要在另一个AsuncTask中使用AcuncTask的情况:/