Java 从Android中的AsyncTask返回值

Java 从Android中的AsyncTask返回值,java,android,asynchronous,android-asynctask,return,Java,Android,Asynchronous,Android Asynctask,Return,一个简单的问题:是否可以在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

一个简单的问题:是否可以在
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?
    }
}
编辑: 很久以前有人问我对Java不熟悉的地方,现在我对它有了更好的了解,我将做一个简短的总结:

异步任务的要点是任务是
asynchronous
,这意味着在对任务调用
execute()
之后,任务开始在自己的线程上运行。从asynctask返回一个值是没有意义的,因为原始的调用线程已经在做其他事情(因此任务是异步的)

想想时间: 在某个时间点,您启动了一个与主线程并行运行的任务。当并行运行任务完成时,主线程上的时间也已过去。并行任务无法及时返回值到主线程


我来自C,所以我对这件事不太了解。但似乎很多人都有同样的问题,所以我想我应该澄清一下。

这就是为什么。它在UI线程上运行,您可以将结果从那里传递到屏幕(或任何您需要的地方)。在最终结果可用之前不会调用它。如果要提供中间结果,请查看

为什么不调用处理该值的方法

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;
    }
}
公共类MyClass扩展活动{
私有类myTask扩展了AsyncTask{
//启动变量
公共myTask(){
超级();
//我的情妇在这里
}
受保护的Void doInBackground(Void…参数){
//做事
返回null;
}
@凌驾
受保护的void onPostExecute(void结果){
//做事
myMethod(myValue);
}
}
私有myHandledValueType myMethod(值myValue){
//句柄值
返回myHandledValueType;
}
}

对于从异步任务中获取结果的用户,它需要在
super.onpostexcute(result)
之后执行该操作; 因为这意味着后台和异步任务也已经完成。 e、 g:

methodr CheckResponseForPrintent可能是这样的:

private void checkResponseForIntent(MyBeanResult response) {
    if (response == null || response.fault != null) {
        noServiceAvailable();
        return;
    }
 ... or do what ever you want, even call an other async task...
我在使用
异步任务中的
.get()
时遇到了这个问题,而ProgressBar根本无法使用
get()
,实际上,它只在后台工作完成后才工作


我希望它能帮助你。

你可以试试这个:
myvalue=newmytask().execute().get()

负的是它将冻结进程,直到asyncron无法完成

最简单的方法是将调用对象传递到异步任务中(如果愿意,在构造它时):

然后onPostExecuteMethod将调用您喜欢的原始类上的任何方法,例如:

    public void updateAdapter(List<ImageData> images) {
        mImageAdapter.setImages(images);
        mImageAdapter.notifyDataSetChanged();
    }
}
public void updatedapter(列表图像){
mImageAdapter.setImages(图像);
mImageAdapter.notifyDataSetChanged();
}
}

代码示例:活动使用AsyncTask在后台线程中获取值,然后AsyncTask通过调用processValue将结果返回给活动:

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);
    }
  }
}
公共类MyClass扩展活动{
私有void getValue(){
新建MyTask().execute();
}
无效进程值(值myValue){
//句柄值
//更新GUI、显示toast等。。
}
私有类MyTask扩展了AsyncTask{
@凌驾
保护值doInBackground(无效…参数){
//完成任务并返回所需的值
返回值;
}
@凌驾
受保护的void onPostExecute(值结果){
//使用结果调用活动方法
过程值(结果);
}
}
}
您需要使用“协议”
AsynTask
委派或提供数据

代表和数据源

委托是一个对象,当该对象在程序中遇到事件时,它代表另一个对象或与另一个对象协同工作。()

协议是定义某些方法以委派某些行为的接口。


委托:从后台线程中的对象捕获事件


AsynkTask:

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

编辑:如果在doInBackground中调用委托,并且委托尝试编辑某些视图,则该操作将崩溃,因为视图只能由主线程操作



额外的

数据源:在后台线程中为对象提供数据


异步任务:

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);
        }   
    }
}
使用通用参数 例子 按字符串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)
    {
        /* Called once task is done; from UI thread, so you can access your widgets */

        // Process result as you like
    }
}.execute("http://www.example.com/");
newasynctask()
{
@凌驾
受保护的void onPreExecute()
{
/*在任务执行之前调用;从UI线程调用,因此您可以访问您的小部件*/
//可以选择做一些事情,比如显示进度条
};
@凌驾
受保护的YourObject doInBackground(字符串…url)
{
/*从后台线程调用,因此不允许您与UI交互*/
//执行繁重的任务以通过字符串获取对象
//保持清晰和功能性,只需将输入转换为输出并返回即可
YourObject结果=调用服务器(url);
返回结果;
}
@凌驾
受保护的void onPostExecute(YourObject结果)
{
/*任务完成后调用;从UI线程调用,这样您就可以访问您的小部件*/
//根据您的喜好处理结果
}
}.执行(”http://www.example.com/");

将MainActivity传递给Async类,以便访问内部类中的MainActivity函数, 这对我来说很好:

public class MainActivity extends ActionBarActivity {

   void callAsync()
   {
      Async as = new Async(this,12,"Test");
      as.execute();
   }

   public void ReturnThreadResult(YourObject result)
   {
     // TO DO:
     // print(result.toString());

   }
}


public class Async extends AsyncTask<String, String, Boolean> {
    MainActivity parent;
    int param1;
    String param2;

    public Async(MainActivity parent,int param1,String param2){
       this.parent = parent;
       this.param1 = param1;
       this.param2 = param2;
    }

    @Override
    protected void onPreExecute(){};

    @Override
    protected YourObject doInBackground(String... url)
    {
        return result;
    }

    @Override
    protected void onPostExecute(YourObject result)
    {
       // call an external function as a result 
       parent.ReturnThreadResult(result);
    }
  }  
公共类MainActivity扩展了ActionBarActivity{
void callAsync()
{
Async as=新的异步(这个,12,“测试”);
as.execute();
}
public void ReturnThreadResult(YourObject结果)
{
//要做:
//打印(result.toString());
}
}
公共类异步扩展异步任务{
主要活动父母;
int参数1
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) {

    }
}
// this refers to Activity
this.runOnUiThread(new Runnable() {
    @Override
    public void run() {
    // Here you can edit views when task notify some changes from background thread
        textView.setText(someValue);
    }
});
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>
Result = task(Params)
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)
    {
        /* Called once task is done; from UI thread, so you can access your widgets */

        // Process result as you like
    }
}.execute("http://www.example.com/");
public class MainActivity extends ActionBarActivity {

   void callAsync()
   {
      Async as = new Async(this,12,"Test");
      as.execute();
   }

   public void ReturnThreadResult(YourObject result)
   {
     // TO DO:
     // print(result.toString());

   }
}


public class Async extends AsyncTask<String, String, Boolean> {
    MainActivity parent;
    int param1;
    String param2;

    public Async(MainActivity parent,int param1,String param2){
       this.parent = parent;
       this.param1 = param1;
       this.param2 = param2;
    }

    @Override
    protected void onPreExecute(){};

    @Override
    protected YourObject doInBackground(String... url)
    {
        return result;
    }

    @Override
    protected void onPostExecute(YourObject result)
    {
       // call an external function as a result 
       parent.ReturnThreadResult(result);
    }
  }