Подтвердить что ты не робот

Возврат данных из AsyncTask без блокировки пользовательского интерфейса

У меня есть концептуальная проблема, связанная с классом AsyncTask. Мы используем AsyncTask, чтобы основной пользовательский интерфейс не блокировался. Но предположим, что я хочу получить некоторые данные из памяти устройства, и для этого я использую класс AsyncTask. Соответствующая строка кода будет выглядеть следующим образом (при условии, что тип данных возвращен как String):

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

Не будет ли указанная выше строка блокировать пользовательский интерфейс, победив цель использования AsyncTask? Если да, то как мне получить соответствующие данные без блокировки пользовательского интерфейса? Я хотел бы добавить, что следующей строке кода понадобятся эти данные для выполнения какой-либо задачи и, следовательно, зависит от возвращаемого значения.

Спасибо

4b9b3361

Ответ 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 с обратным вызовом

Ответ 2

Вы не получите результат таким образом. См. Эту ссылку для примера: https://github.com/levinotik/ReusableAsyncTask/tree/master/src/com/example

В принципе, вот что вам нужно сделать:

  • Определите интерфейс (= прослушиватель), который ваша деятельность реализует
  • Установить прослушиватель в асинтете
  • Вызовите yourListener.yourMethod() в onPostExecute

Ответ 3

Когда выполняется асинхронная задача, задача выполняет 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());
 }
 }

Рассмотрим использование robospice (альтернатива AsyncTask. https://github.com/octo-online/robospice.

Сделать асинхронные вызовы, уведомлять о потоке ui.