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

我有两门课。现在,在我的主活动中,我需要从AsyncTask中的OnPostExecute()中获得结果。如何将结果传递给我的主活动?

下面是示例代码。

我的主要活动。

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


}


}
303384 次浏览

你可以调用AsyncTaskget()方法(或者重载的get(long, TimeUnit))。此方法将阻塞,直到AsyncTask完成其工作,此时它将返回Result

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

有以下几种选择:

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

    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 your Activity. You would instantiate the task with something like 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
    ...
    }
    

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

例如,如果你的AsyncTask的结果是一个字符串,在你的Activity中创建一个公共静态字符串

public static String dataFromAsyncTask;

然后,在AsyncTask的onPostExecute中,简单地对主类进行静态调用并设置值。

MainActivity.dataFromAsyncTask = "result blah";

容易:

  1. 创建interface类,其中String output是可选的,或者可以是你想返回的任何变量。

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

     public class MyAsyncTask extends AsyncTask<Void, Void, String> {
    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.
    }
    }
    

更新

我不知道这是你们很多人的最爱。下面是使用interface的简单而方便的方法。

仍然使用相同的interface。供参考,你可以把它合并到AsyncTask类中。

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

在你的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.
}
}

正如你可以看到上面的两个解决方案,第一个和第三个,它需要创建方法processFinish,另一个,方法是在调用者参数内部。第三种方法更加简洁,因为没有嵌套的匿名类。

提示:将String outputString responseString result更改为不同的匹配类型,以获得不同的对象。

在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. 创建实现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. Add in Main Activity

    // 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();
    ...
    }
    

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

我已经声明了一个回调接口

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

然后创建异步任务来响应所有类型的并行请求

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


}

然后在活动类中单击按钮时调用异步任务。

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

我希望这对你有帮助,编码快乐:)

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

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

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

ProgressDialog loadingdialog;

创建一个函数,在操作结束时关闭对话框。

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

您可以编写自己的侦听器。它与HelmiB的答案相同,但看起来更自然:

创建监听器接口:

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

然后写你的异步任务:

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

最后在activity中实现监听器:

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...
}

为什么人们把事情搞得这么难。

这应该足够了。

不要在异步任务上实现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时,我想提一些事情。这将帮助您防止崩溃和内存管理。正如上面已经提到的interface的答案,我们也称它们为回调。它们将作为一个告密者工作,但永远不会发送Activityinterface的<强大的>强大的引用,在这些情况下总是使用引用。

请参考下面的截图,以了解如何导致问题。

enter image description here

正如你所看到的,如果我们用<强大的>强大的引用开始AsyncTask,那么就不能保证我们的Activity/Fragment在我们获得数据之前是活的,所以在这种情况下最好使用WeakReference,这也有助于内存管理,因为我们永远不会持有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);
}
}

你需要使用“协议”来委托或提供数据给AsynTask

委托和数据源

委托是一个对象,当另一个对象在程序中遇到事件时,它代表另一个对象或与另一个对象协调行动。(苹果的定义)

协议是定义一些方法来委托一些行为的接口。

这是一个完整的例子!!< / >

试试这个:

public class SomAsyncTask extends AsyncTask<String, Integer, JSONObject> {


private CallBack callBack;


public interface CallBack {
void async( JSONObject jsonResult );
void sync( JSONObject jsonResult );
void progress( Integer... status );
void cancel();
}


public SomAsyncTask(CallBack callBack) {
this.callBack = callBack;
}


@Override
protected JSONObject doInBackground(String... strings) {


JSONObject dataJson = null;


//TODO query, get some dataJson


if(this.callBack != null)
this.callBack.async( dataJson );// asynchronize with MAIN LOOP THREAD


return dataJson;


}


@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);


if(this.callBack != null)
this.callBack.progress(values);// synchronize with MAIN LOOP THREAD


}


@Override
protected void onPostExecute(JSONObject jsonObject) {
super.onPostExecute(jsonObject);


if(this.callBack != null)
this.callBack.sync(jsonObject);// synchronize with MAIN LOOP THREAD
}


@Override
protected void onCancelled() {
super.onCancelled();


if(this.callBack != null)
this.callBack.cancel();


}
}

用法示例:

public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);


final Context _localContext = getContext();
SomeAsyncTask.CallBack someCallBack = new SomeAsyncTask.CallBack() {


@Override
public void async(JSONObject jsonResult) {//async thread
//some async process, e.g. send data to server...
}


@Override
public void sync(JSONObject jsonResult) {//sync thread
//get result...


//get some resource of Activity variable...
Resources resources = _localContext.getResources();
}


@Override
public void progress(Integer... status) {//sync thread
//e.g. change status progress bar...
}


@Override
public void cancel() {


}


};


new SomeAsyncTask( someCallBack )
.execute("someParams0", "someParams1", "someParams2");


}

可能有点过分了,但我为执行代码和结果都提供了回调。显然,为了线程安全,你要小心你在执行回调中访问的内容。

AsyncTask实现:

public class AsyncDbCall<ExecuteType,ResultType> extends AsyncTask<ExecuteType, Void,
ResultType>
{
public interface ExecuteCallback<E, R>
{
public R execute(E executeInput);
}
public interface PostExecuteCallback<R>
{
public void finish(R result);
}


private PostExecuteCallback<ResultType> _resultCallback = null;
private ExecuteCallback<ExecuteType,ResultType> _executeCallback = null;




AsyncDbCall(ExecuteCallback<ExecuteType,ResultType> executeCallback, PostExecuteCallback<ResultType> postExecuteCallback)
{
_resultCallback = postExecuteCallback;
_executeCallback = executeCallback;
}


AsyncDbCall(ExecuteCallback<ExecuteType,ResultType> executeCallback)
{
_executeCallback = executeCallback;
}


@Override
protected ResultType doInBackground(final ExecuteType... params)
{
return  _executeCallback.execute(params[0]);
}


@Override
protected void onPostExecute(ResultType result)
{
if(_resultCallback != null)
_resultCallback.finish(result);
}
}

一个回调:

 AsyncDbCall.ExecuteCallback<Device, Device> updateDeviceCallback = new
AsyncDbCall.ExecuteCallback<Device, Device>()
{
@Override
public Device execute(Device device)
{
deviceDao.updateDevice(device);
return device;
}
};

最后执行异步任务:

 new AsyncDbCall<>(addDeviceCallback, resultCallback).execute(device);

希望你已经通过,如果没有,请阅读。

https://developer.android.com/reference/android/os/AsyncTask

根据结果数据的性质,您应该选择您能想到的最佳选项。

使用接口是一个很好的选择

其他的选择是…

  • 如果AsyncTask类定义在你想要的类内部 使用结果。使用静态全局变量或get(),从 外层类(易失性变量如果必要)。但是应该注意AsyncTask 进步,或者至少应该确保它已经完成了任务,结果是 可通过global variable / get()方法获得。你可以使用 轮询,onProgressUpdate(进步…),同步或接口(最适合你)

  • 如果Result兼容为sharedPreference条目,或者可以将其保存为内存中的文件,则甚至可以从保存它 后台任务本身,可以使用onPostExecute ()方法

  • .当结果在内存中可用时得到通知
  • 如果字符串足够小,并且将与an的开头一起使用 活动。可以使用意图 (putExtra ()) onPostExecute(),但记住,静态上下文不是那么安全

  • .处理 方法中调用静态方法,如果可能的话 onPostExecute()方法,其结果是您的参数