【问题标题】:Returning data from AsyncTask without blocking UI从 AsyncTask 返回数据而不阻塞 UI
【发布时间】:2013-03-26 11:03:39
【问题描述】:

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

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

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

谢谢

【问题讨论】:

标签: android android-asynctask


【解决方案1】:

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 with Callback的答案

【讨论】:

  • 我不想显示该数据,我想使用该数据。当我用谷歌搜索我的问题时,我得到了类似的结果。
  • @addresseeerajat 完整阅读答案。最后两行讨论了带有回调的 AsyncTask,转到链接一次
  • 好的,我有一些模糊的想法,但我希望将这些数据传递给主 UI 线程。
  • @addresseeerajat 回调会将数据返回到您的 UI 线程。只需使用相同的代码。
  • @Alioo 如果将此类包含为内部类,则可以从 onCreate 中的父类获取上下文。其次,如果您将其作为单独的类包含,请为 bg 任务使用单个参数构造函数。并从该论点中获取上下文
【解决方案2】:

当一个异步任务执行时,该任务会经过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

【讨论】:

    【解决方案3】:

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

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

    • 定义您的 Activity 实现的接口(= 侦听器)
    • 在异步任务中设置监听器
    • 在 onPostExecute 中调用 yourListener.yourMethod()

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-21
      • 2015-05-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多