从Android中的AsyncTask返回一个值[重复]
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从Android中的AsyncTask返回一个值[重复]相关的知识,希望对你有一定的参考价值。
这个问题在这里已有答案:
一个简单的问题:是否有可能在AsyncTask
中返回一个值?
//AsyncTask is a member class
private class MyTask extends AsyncTask<Void, Void, Void>{
protected Void doInBackground(Void... params) {
//do stuff
return null;
}
@Override
protected void onPostExecute(Void result) {
//do stuff
//how to return a value to the calling method?
}
}
然后在我的Activity
/ Fragment
内:
// The task is started from activity
myTask.execute()
// something like this?
myvalue = myTask.getvalue()
编辑:这是很久以前我不熟悉Java的问题,现在我对它更好了,我会做一个简短的总结:
异步任务的重点是任务是asynchronous
,这意味着在您对任务调用execute()
之后,任务开始在自己的线程上运行。从asynctask返回一个值是没有意义的,因为原始调用线程已经继续做其他事情(因此任务是异步的)。
想想时间:在某个时间点,您启动了一个与主线程并行运行的任务。当并行运行任务完成时,主线程上也经过了时间。并行任务无法及时返回以将值返回给主线程。
我是从C来的,所以我对此并不了解。但似乎很多人都有同样的问题,所以我想我会稍微澄清一下。
为什么不调用一个处理值的方法?
public class MyClass extends Activity {
private class myTask extends AsyncTask<Void, Void, Void> {
//initiate vars
public myTask() {
super();
//my params here
}
protected Void doInBackground(Void... params) {
//do stuff
return null;
}
@Override
protected void onPostExecute(Void result) {
//do stuff
myMethod(myValue);
}
}
private myHandledValueType myMethod(Value myValue) {
//handle value
return myHandledValueType;
}
}
这就是onPostExecute()
的用途。它在UI线程上运行,您可以将结果从那里传送到屏幕(或您需要的任何其他地方)。在最终结果可用之前不会调用它。如果您想提供中间结果,请查看onProgressUpdate()
最简单的方法是将调用对象传递给异步任务(如果您愿意,可以在构建它时):
public class AsyncGetUserImagesTask extends AsyncTask<Void, Void, Void> {
private MyImagesPagerFragment mimagesPagerFragment;
private ArrayList<ImageData> mImages = new ArrayList<ImageData>();
public AsyncGetUserImagesTask(MyImagesPagerFragment imagesPagerFragment) {
this.mimagesPagerFragment = imagesPagerFragment;
}
@Override
public Void doInBackground(Void... records) {
// do work here
return null;
}
@Override
protected void onPostExecute(Void result) {
mimagesPagerFragment.updateAdapter(mImages);
}
}
并且在调用类(您的活动或片段)中执行任务:
public class MyImagesPagerFragment extends Fragment {
@Override
public void onCreate(Bundle savedInstanceState) {
AsyncGetUserImagesTask mGetImagesTask = new AsyncGetUserImagesTask(this);
mGetImagesTask.execute();
}
然后onPostExecuteMethod将调用您喜欢的原始类上的任何方法,例如:
public void updateAdapter(List<ImageData> images) {
mImageAdapter.setImages(images);
mImageAdapter.notifyDataSetChanged();
}
}
你可以尝试这个:myvalue = new myTask().execute().get();
减去它会冻结进程,直到asyncron不会完成;
代码示例:Activity使用AsyncTask在后台线程中获取值,然后AsyncTask通过调用processValue将结果返回给Activity:
public class MyClass extends Activity {
private void getValue() {
new MyTask().execute();
}
void processValue(Value myValue) {
//handle value
//Update GUI, show toast, etc..
}
private class MyTask extends AsyncTask<Void, Void, Value> {
@Override
protected Value doInBackground(Void... params) {
//do stuff and return the value you want
return Value;
}
@Override
protected void onPostExecute(Value result) {
// Call activity method with results
processValue(result);
}
}
}
您需要使用“协议”委派或向AsynTask
提供数据。
代表和数据来源
委托是一个对象,当该对象遇到程序中的事件时,该对象代表另一个对象或与另一个对象协调。 (Apple definition)
协议是定义一些委托某些行为的方法的接口。
DELEGATE:从后台线程中的对象中截取事件
的AsyncTask:
public final class TaskWithDelegate extends AsyncTask<..., ..., ...> {
//declare a delegate with type of protocol declared in this task
private TaskDelegate delegate;
//here is the task protocol to can delegate on other object
public interface TaskDelegate {
//define you method headers to override
void onTaskEndWithResult(int success);
void onTaskFinishGettingData(Data result);
}
@Override
protected Integer doInBackground(Object... params) {
//do something in background and get result
if (delegate != null) {
//return result to activity
delegate.onTaskFinishGettingData(result);
}
}
@Override
protected void onPostExecute(Integer result) {
if (delegate != null) {
//return success or fail to activity
delegate.onTaskEndWithResult(result);
}
}
}
活动:
public class DelegateActivity extends Activity implements TaskDelegate {
void callTask () {
TaskWithDelegate task = new TaskWithDelegate;
//set the delegate of the task as this activity
task.setDelegate(this);
}
//handle success or fail to show an alert...
@Override
void onTaskEndWithResult(int success) {
}
//handle data to show them in activity...
@Override
void onTaskFinishGettingData(Data result) {
}
}
编辑:如果您在doInBackground中调用委托,并且委托尝试编辑某个视图,那将崩溃,因为视图只能由主线程操纵。
额外
DATASOURCE:在后台线程中为对象提供数据
的AsyncTask:
public final class TaskWithDataSource extends AsyncTask<..., ..., ...> {
//declare a datasource with type of protocol declared in this task
private TaskDataSource dataSource;
private Object data;
//here is the task protocol to can provide data from other object
public interface TaskDataSource {
//define you method headers to override
int indexOfObject(Object object);
Object objectAtIndex(int index);
}
@Override
protected void onPreExecute(Integer result) {
if (dataSource != null) {
//ask for some data
this.data = dataSource.objectAtIndex(0);
}
}
@Override
protected Integer doInBackground(Object... params) {
//do something in background and get result
int index;
if (dataSource != null) {
//ask for something more
index = dataSource.indexOfObject(this.data);
}
}
}
活动:
public class DataSourceActivity extends Activity implements TaskDataSource {
void callTask () {
TaskWithDataSource task = new TaskWithDataSource;
//set the datasource of the task as this activity
task.setDataSource(this);
}
//send some data to the async task when it is needed...
@Override
Object objectAtIndex(int index) {
return new Data(index);
}
//send more information...
@Override
int indexOfObject(Object object) {
return new object.getIndex();
}
}
使用通用参数
AsyncTask<Params, Progress, Result>
Params
- 任务的输入数据类型Progress
- 如何告知世界进步Result
- 任务的输出数据类型
想想
Result = task(Params)
例
通过字符串URL加载YourObject
:
new AsyncTask<String, Void, YourObject>()
{
@Override
protected void onPreExecute()
{
/* Called before task execution; from UI thread, so you can access your widgets */
// Optionally do some stuff like showing progress bar
};
@Override
protected YourObject doInBackground(String... url)
{
/* Called from background thread, so you're NOT allowed to interact with UI */
// Perform heavy task to get YourObject by string
// Stay clear & functional, just convert input to output and return it
YourObject result = callTheServer(url);
return result;
}
@Override
protected void onPostExecute(YourObject result)
{
以上是关于从Android中的AsyncTask返回一个值[重复]的主要内容,如果未能解决你的问题,请参考以下文章