15

我有一个与类有关的概念问题AsyncTask。我们使用AsyncTask这样主 UI 不会被阻塞。但是假设,我想从设备的内存中检索一些数据,为此我使用 AsyncTask 类。相关代码行如下(假设返回的数据类型为String):

  //code
    String data = new ExtendedAsyncTask().execute(param1, param2).get();
  //use this returned value.

上面的行不会阻塞用户界面,破坏使用的目的AsyncTask吗?如果是,那么如何在不阻塞 UI 的情况下获取相关数据?我想补充一点,下一行代码将需要这些数据来执行某些任务,因此取决于返回的值。

谢谢

4

3 回答 3

20

get() method will block the UI thread. 要获取相关数据,您需要从 doInBackground 返回值并捕获 onPostExecute 参数中的值。

doInBackground 返回的值被 onPostExecute 方法捕获

例子:

public class BackgroundTask extends AsyncTask<String, Integer, String >{
       private ProgressDialog mProgressDialog;
       int progress;
       public BackgroundTask() {
           mProgressDialog = new ProgressDialog(context);
             mProgressDialog.setMax(100);
             mProgressDialog.setProgress(0);
    }

       @Override
    protected void onPreExecute() {
           mProgressDialog =ProgressDialog.show(context, "", "Loading...",true,false);
        super.onPreExecute();
    }
     @Override
     protected void onProgressUpdate(Integer... values) {
     setProgress(values[0]);
  }

    @Override
    protected String doInBackground(String... params) {
            String data=getDatafromMemoryCard();    

        return data;  // return data you want to use here
    }
    @Override
    protected void onPostExecute(String  result) {  // result is data returned by doInBackground
        Toast.makeText(context, result, Toast.LENGTH_LONG).show();
        mProgressDialog.dismiss();
        super.onPostExecute(result);
    }
   }

如果您在单独的类中使用 asynctask,请使用带有回调接口的 AsyncTask,如下所示

这是我之前提供的关于带有回调的相同 AsyncTask的答案

于 2013-03-26T11:06:38.860 回答
1

当一个异步任务被执行时,任务会经过 4 个步骤:

1.onPreExecute(), invoked on the UI thread before the task is executed. use this to diaply progress dialog.

2.doInBackground(Params...), invoked on the background thread immediately after onPreExecute() finishes executing. Can also use publishProgress(Progress...) to publish one or more units of progress. These values are published on the UI thread, in the onProgressUpdate(Progress...) step.

3.onProgressUpdate(Progress...), invoked on the UI thread after a call to publishProgress(Progress...). Used to publish progress.

4.onPostExecute(Result), invoked on the UI thread after the background computation finishes. The result of the background computation is passed to this step as a parameter.

在您的活动 onCreate()

    TextView tv;
   @Override
   protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);  
    setContentView(R.layout.activity_main);
    tv= (TextView)findViewById(R.id.textView);
    new TheTask().execute();
      
  }
class TheTask extends AsyncTask<Void, Void,String> {

  protected void onPreExecute() {
  //dispaly progress dialog
 }

 protected String doInBackground(Void... params) {
   //do network operation
     return "hello"; 
 }

 protected void onPostExecute(String result) {  
  //dismiss dialog. //set hello to textview
      //use the returned value here.
     tv.setText(result.toString());
 }
 }

进行异步调用,在 ui 线程上通知。

更新: AsyncTask 已弃用。切换到 kotlin 协程。https://developer.android.com/kotlin/coroutines

于 2013-03-26T11:11:53.863 回答
0

你不会以这种方式得到结果。有关示例,请参见此链接:https ://github.com/levinotik/ReusableAsyncTask/tree/master/src/com/example

基本上,这是您需要做的:

  • 定义您的活动实现的接口(= 侦听器)
  • 在 asynctask 中设置监听器
  • 在 onPostExecute 中调用 yourListener.yourMethod()
于 2013-03-26T11:09:28.677 回答