我有这两个班。我的主要活动和扩展AsyncTask
的活动,现在在我的主要活动中,我需要从OnPostExecute()
中的AsyncTask
获取结果。如何将结果传递给我的主要活动?
以下是示例代码。
我的主要活动。
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);
}
}
答案 0 :(得分:693)
易:
创建interface
类,其中String output
是可选的,或者可以是您想要返回的任何变量。
public interface AsyncResponse {
void processFinish(String output);
}
转到AsyncTask
班级,并将接口AsyncResponse
声明为字段:
public class MyAsyncTask extends AsyncTask<Void, Void, String> {
public AsyncResponse delegate = null;
@Override
protected void onPostExecute(String result) {
delegate.processFinish(result);
}
}
在您的主要活动中,您需要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 output
,String response
和String result
更改为不同的匹配类型,以获取不同的对象。
答案 1 :(得分:23)
有几个选择:
将AsyncTask
课程嵌套在Activity
课程中。假设您在多个活动中不使用相同的任务,这是最简单的方法。您的所有代码都保持不变,您只需将现有任务类移动到活动类中的嵌套类。
public class MyActivity extends Activity {
// existing Activity code
...
private class MyAsyncTask extends AsyncTask<String, Void, String> {
// existing AsyncTask code
...
}
}
为AsyncTask
创建一个自定义构造函数,该构造函数引用您的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
...
}
答案 2 :(得分:16)
我觉得下面的方法非常简单。
我已经声明了一个回调接口
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.." });
}
});
}
}
由于
答案 3 :(得分:14)
您可以在Main类中尝试此代码。 这对我有用,但我用其他方式实现了方法
class C(object):
def __init__(self,c):
self.content = c
def __bool__(self):
return bool(self.content)
__nonzero__ = __bool__
答案 4 :(得分:7)
这个答案可能会迟到,但我想在Activity
依赖AsyncTask
时提及一些事情。这将有助于您防止崩溃和内存管理。正如上面的回答中提到的那样,我们也会使用interface
来回复它们。他们将作为线人,但永远不会发送{strong>强引用Activity
或interface
在这些情况下始终使用弱引用。
请参阅下面的屏幕截图,了解这可能会导致问题。
正如您所看到的,如果我们使用强引用启动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
工具interface
,并override
此强制方法。
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);
}
}
答案 5 :(得分:6)
您可以在几行中完成,只需在调用AsyncTask时覆盖onPostExecute。以下是您的示例:
new AasyncTask()
{
@Override public void onPostExecute(String result)
{
// do whatever you want with result
}
}.execute(a.targetServer);
我希望它对你有所帮助,快乐的编码:)
答案 6 :(得分:5)
:
`
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();
}`
答案 7 :(得分:4)
为什么人们会这么努力。
这应该足够了。
不要在异步任务上实现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");
}
}
答案 8 :(得分:3)
您可以调用AsyncTask
的{{3}}方法(或重载的get()
)。此方法将阻止,直到AsyncTask
完成其工作,此时它将返回Result
。
在创建/启动异步任务和调用get
方法之间进行其他工作是明智的,否则您不能非常有效地利用异步任务。
答案 9 :(得分:2)
嗨,你可以做这样的事情:
创建实现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");
}
}
}
添加主要活动
// 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();
...
}
答案 10 :(得分:2)
您可以编写自己的监听器。它与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...
}
答案 11 :(得分:1)
在Activity类中创建一个静态成员。然后在onPostExecute
例如,如果AsyncTask的结果是String,请在Activity中创建一个公共静态字符串
public static String dataFromAsyncTask;
然后,在AsyncTask的onPostExecute
中,只需对主类进行静态调用并设置值。
MainActivity.dataFromAsyncTask = "result blah";
答案 12 :(得分:0)
我通过使用线程和处理程序/消息使其工作。 步骤如下: 声明进度对话框
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();
}
答案 13 :(得分:0)
您需要使用&#34;协议&#34; 委派或向AsynTask
提供数据。
代表和数据来源
委托是一个对象,当该对象遇到程序中的事件时,该对象代表另一个对象或与另一个对象协同工作。 (Apple definition)
协议是定义一些委托某些行为的方法的接口。
答案 14 :(得分:0)
尝试一下:
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");
}
答案 15 :(得分:0)
可能有点落伍,但是我提供了执行代码和结果的回调。显然,为了线程安全,您需要注意在执行回调中访问的内容。
AsyncTask实现:
12345679.00
回调:
let x = 123456789.998;
const formatter = new Intl.NumberFormat("en-US", {
style: "decimal",
minimumFractionDigits: 2,
maximumFractionDigits: 2,
useGrouping: false
});
let n = formatter.format(x);
console.log(n);
最后执行异步任务:
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);
}
}
答案 16 :(得分:0)
希望您经历过this,否则请继续阅读。
https://developer.android.com/reference/android/os/AsyncTask
根据结果数据的性质,您应该选择可以想到的最佳选择。
使用界面
是一个不错的选择一些其他选项。.
如果您要在类中定义AsyncTask类 使用结果。使用静态全局变量或get(),从 外部类(易失性变量,如有必要)。但应了解AsyncTask progress ,或至少应确保它已完成任务且结果为 可通过全局变量/ get()方法获得。你可以用 轮询,onProgressUpdate(Progress...),同步或接口(最适合您的情况)
如果结果兼容作为sharedPreference条目,或者可以另存为文件在内存中,则可以保存
后台任务本身,可以使用 onPostExecute()方法
当结果在内存中可用时得到通知。
如果字符串足够小,并且将以 活动。可以在其中使用意图( putExtra()) onPostExecute(),但请记住,静态上下文并不那么安全 处理。
如果可能的话,您可以从以下位置调用静态方法: onPostExecute()方法,结果是您的参数