简体   繁体   English

从AsyncTask返回数据而不阻止UI

[英]Returning data from AsyncTask without blocking UI

I have a conceptual problem related to AsyncTask class. 我有一个与AsyncTask类相关的概念问题。 We use AsyncTask so that the main UI is not blocked. 我们使用AsyncTask因此不会阻止主UI。 But suppose, I want to retrieve some data from the device's memory, and I use AsyncTask class for this. 但是假设,我想从设备的内存中检索一些数据,为此我使用AsyncTask类。 The relevant line of the code will be as follows (assuming the data type returned is String): 代码的相关行如下(假设返回的数据类型是String):

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

Won't the above line block the UI, defeating the purpose of using the AsyncTask ? 上面的行不会阻止UI,打败使用AsyncTask的目的吗? If yes, then how do I get the relevant data without blocking UI ? 如果是,那么如何在不阻止UI的情况下获取相关数据? I would like to add that the next line of code will need this data to perform some task, and hence depends on the returned value. 我想补充一点,下一行代码将需要这些数据来执行某些任务,因此取决于返回的值。

Thanks 谢谢

get() method will block the UI thread . get() method will block the UI thread To get the relavent data you need to return the value from doInBackground and capture the value in onPostExecute parameter. 要获取相关数据,您需要从doInBackground返回值并捕获onPostExecute参数中的值。

Value returned by doInBackground is captured by onPostExecute method doInBackground返回的值由onPostExecute方法捕获

Example: 例:

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

If you are using asynctask in separate class, then use AsyncTask with callback interface like this 如果你在单独的类中使用asynctask,那么像这样使用带有回调接口的AsyncTask

Here is the answer I have provided earlier about the same AsyncTask with Callback 以下是我之前提供的关于使用Callback的相同AsyncTask的答案

You don't get the result this way. 你没有这样得到结果。 See this link for an example : https://github.com/levinotik/ReusableAsyncTask/tree/master/src/com/example 请参阅此链接以获取示例: https//github.com/levinotik/ReusableAsyncTask/tree/master/src/com/example

Basically, here is what you need to do : 基本上,这是你需要做的:

  • Define an interface (= a listener) that your activity implements 定义您的活动实现的接口(=侦听器)
  • Set the listener in the asynctask 在asynctask中设置监听器
  • Call yourListener.yourMethod() in the onPostExecute 在onPostExecute中调用yourListener.yourMethod()

When an asynchronous task is executed, the task goes through 4 steps: 执行异步任务时,任务将执行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.

In your activity onCreate() 在你的活动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());
 }
 }

Consider using robospice (An alternative to AsyncTask. https://github.com/octo-online/robospice . 考虑使用robospice(到的AsyncTask的替代品。 https://github.com/octo-online/robospice

Make asynchronous calls, Notifies on the ui thread. 进行异步调用,在ui线程上通知。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM