Как получить результат OnPostExecute () для основной деятельности, потому что AsyncTask является отдельным классом?

362

У меня есть эти два класса. Моя основная деятельность и тот , который расширяет AsyncTask, сейчас в моей основной деятельности мне нужно , чтобы получить результат от OnPostExecute()в AsyncTask. Как я могу передать или получить результат в моей основной деятельности?

Вот примеры кодов.

Моя основная деятельность.

public class MainActivity extends Activity{

    AasyncTask asyncTask = new AasyncTask();

    @Override
    public void onCreate(Bundle aBundle) {
        super.onCreate(aBundle);            

        //Calling the AsyncTask class to start to execute.  
        asyncTask.execute(a.targetServer); 

        //Creating a TextView.
        TextView displayUI = asyncTask.dataDisplay;
        displayUI = new TextView(this);
        this.setContentView(tTextView); 
    }

}

Это класс AsyncTask

public class AasyncTask extends AsyncTask<String, Void, String> {

TextView dataDisplay; //store the data  
String soapAction = "http://sample.com"; //SOAPAction header line. 
String targetServer = "https://sampletargeturl.com"; //Target Server.

//SOAP Request.
String soapRequest = "<sample XML request>";    



@Override
protected String doInBackground(String... string) {

String responseStorage = null; //storage of the response

try {


    //Uses URL and HttpURLConnection for server connection. 
    URL targetURL = new URL(targetServer);
    HttpURLConnection httpCon = (HttpURLConnection) targetURL.openConnection();
    httpCon.setDoOutput(true);
    httpCon.setDoInput(true);
    httpCon.setUseCaches(false); 
    httpCon.setChunkedStreamingMode(0);

    //properties of SOAPAction header
    httpCon.addRequestProperty("SOAPAction", soapAction);
    httpCon.addRequestProperty("Content-Type", "text/xml; charset=utf-8"); 
    httpCon.addRequestProperty("Content-Length", "" + soapRequest.length());
    httpCon.setRequestMethod(HttpPost.METHOD_NAME);


    //sending request to the server.
    OutputStream outputStream = httpCon.getOutputStream(); 
    Writer writer = new OutputStreamWriter(outputStream);
    writer.write(soapRequest);
    writer.flush();
    writer.close();


    //getting the response from the server
    InputStream inputStream = httpCon.getInputStream(); 
    BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
    ByteArrayBuffer byteArrayBuffer = new ByteArrayBuffer(50);

    int intResponse = httpCon.getResponseCode();

    while ((intResponse = bufferedReader.read()) != -1) {
        byteArrayBuffer.append(intResponse);
    }

    responseStorage = new String(byteArrayBuffer.toByteArray()); 

    } catch (Exception aException) {
    responseStorage = aException.getMessage(); 
    }
    return responseStorage;
}

protected void onPostExecute(String result) {

    aTextView.setText(result);

}       

}   
Стелла
источник
Вы можете создать интерфейс, подобный объясненному HelmiB, или создать локальный приемник вещания. Пример реализации приемника вещания можно посмотреть здесь: wiki.workassis.com/android-local-broadcast-receiver
Bikesh M
Почему бы не использовать шаблон Observer?
JAAAY

Ответы:

751

Легко:

  1. Создайте interfaceкласс, где String outputнеобязательно, или может быть любые переменные, которые вы хотите вернуть.

    public interface AsyncResponse {
        void processFinish(String output);
    }
  2. Перейдите в свой AsyncTaskкласс и объявите интерфейс AsyncResponseкак поле:

    public class MyAsyncTask extends AsyncTask<Void, Void, String> {
      public AsyncResponse delegate = null;
    
        @Override
        protected void onPostExecute(String result) {
          delegate.processFinish(result);
        }
     }
  3. В вашей основной деятельности вам нужно implementsинтерфейс AsyncResponse.

    public class MainActivity implements AsyncResponse{
      MyAsyncTask asyncTask =new MyAsyncTask();
    
      @Override
      public void onCreate(Bundle savedInstanceState) {
    
         //this to set delegate/listener back to this class
         asyncTask.delegate = this;
    
         //execute the async task 
         asyncTask.execute();
      }
    
      //this override the implemented method from asyncTask
      @Override
      void processFinish(String output){
         //Here you will receive the result fired from async class 
         //of onPostExecute(result) method.
       }
     }

ОБНОВИТЬ

Я не знал, что это такой любимый для многих из вас. Итак, вот простой и удобный способ использования interface.

все еще использую то же самое interface. К вашему сведению, вы можете объединить это в AsyncTaskклассе.

в AsyncTaskклассе:

public class MyAsyncTask extends AsyncTask<Void, Void, String> {

  // you may separate this or combined to caller class.
  public interface AsyncResponse {
        void processFinish(String output);
  }

  public AsyncResponse delegate = null;

    public MyAsyncTask(AsyncResponse delegate){
        this.delegate = delegate;
    }

    @Override
    protected void onPostExecute(String result) {
      delegate.processFinish(result);
    }
}

делай это в своем Activityклассе

public class MainActivity extends Activity {

   MyAsyncTask asyncTask = new MyAsyncTask(new AsyncResponse(){

     @Override
     void processFinish(String output){
     //Here you will receive the result fired from async class 
     //of onPostExecute(result) method.
     }
  }).execute();

 }

Или снова реализовать интерфейс в Activity

public class MainActivity extends Activity 
    implements AsyncResponse{

    @Override
    public void onCreate(Bundle savedInstanceState) {

        //execute the async task 
        new MyAsyncTask(this).execute();
    }

    //this override the implemented method from AsyncResponse
    @Override
    void processFinish(String output){
        //Here you will receive the result fired from async class 
        //of onPostExecute(result) method.
    }
}

Как вы можете видеть 2 решения выше, первое и третье, он должен создать метод processFinish, другое, метод находится внутри параметра вызывающего. Третий более аккуратный, потому что нет вложенного анонимного класса. Надеюсь это поможет

Совет : Измените String output, String responseи String resultна разные подходящие типы, чтобы получить разные объекты.

HelmiB
источник
20
Полностью написал все это, а затем увидел твой ответ :) Вот так думать! +1. Также таким образом несколько вещей могут слушать результаты AsyncTask!
Ролок
8
Я получаю исключение nullpointer, потому что для делегата установлено значение null, пожалуйста, уточните его
Reyjohn
2
Просто примечание для разработчиков .net, для этого можно использовать AutoResetEvents, а также есть java-реализация для autoresetevents, но это намного чище. Кстати, поток ProcessFinish безопасен?
Syler
13
для всех тех, кто получает нулевой указатель, передайте ваш интерфейс конструктору класса asyncTask, затем присвойте его переменной и затем вызовите processfinish () для этой переменной. Для справки см. Принятый ответ. stackoverflow.com/questions/9963691/…
Солнечный
2
@ Санни, ты прав ... также мы должны инициализировать асинхронный объект для async.delegate = this; работать ..
Ninja_Coder
24

Есть несколько вариантов:

  • Гнездо AsyncTaskкласс в вашем Activityклассе. Предполагая, что вы не используете одну и ту же задачу в нескольких действиях, это самый простой способ. Весь ваш код остается прежним, вы просто перемещаете существующий класс задач во вложенный класс внутри класса вашей деятельности.

    public class MyActivity extends Activity {
        // existing Activity code
        ...
    
        private class MyAsyncTask extends AsyncTask<String, Void, String> {
            // existing AsyncTask code
            ...
        }
    }
  • Создайте собственный конструктор, AsyncTaskкоторый будет ссылаться на ваш Activity. Вы могли бы создать задачу с чем-то вроде new MyAsyncTask(this).execute(param1, param2).

    public class MyAsyncTask extends AsyncTask<String, Void, String> {
        private Activity activity;
    
        public MyAsyncTask(Activity activity) {
            this.activity = activity;
        }
    
        // existing AsyncTask code
        ...
    }
quietmint
источник
Во втором варианте: зачем проходить через боль конструктора и поля, если класс - нет static? Просто используйте любой fieldOrMethodиз MyActivityили, MyActivity.this.fieldOrMethodесли он затенен.
TWiStErRob
@TWiStErRob Второй предполагает, что MyAsyncTaskэто не внутренний класс.
тихая мята
1
Ох, извините, private/ protectedдля классов верхнего уровня не допускается, поэтому я подумал, что это не staticвнутренний класс.
TWiStErRob
2
Только будьте осторожны, внутренний класс AsyncTask может быть источником утечек памяти, как описано здесь garena.github.io/blog/2014/09/10/android-memory-leaks
Марк Пазон
2
Удержание ссылки Activity также является утечкой памяти. Подход обратного вызова намного лучше, чем этот
OneCricketeer
19

Я чувствовал, что приведенный ниже подход очень прост.

Я объявил интерфейс для обратного вызова

public interface AsyncResponse {
    void processFinish(Object output);
}

Затем создается асинхронная задача для ответа на все типы параллельных запросов.

 public class MyAsyncTask extends AsyncTask<Object, Object, Object> {

    public AsyncResponse delegate = null;//Call back interface

    public MyAsyncTask(AsyncResponse asyncResponse) {
        delegate = asyncResponse;//Assigning call back interfacethrough constructor
    }

    @Override
    protected Object doInBackground(Object... params) {

      //My Background tasks are written here

      return {resutl Object}

    }

    @Override
    protected void onPostExecute(Object result) {
        delegate.processFinish(result);
    }

}

Затем вызывается асинхронная задача при нажатии кнопки в классе деятельности.

public class MainActivity extends Activity{

    @Override
    public void onCreate(Bundle savedInstanceState) {

    Button mbtnPress = (Button) findViewById(R.id.btnPress);

    mbtnPress.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {

                MyAsyncTask asyncTask =new MyAsyncTask(new AsyncResponse() {

                    @Override
                    public void processFinish(Object output) {
                        Log.d("Response From Asynchronous task:", (String) output);

                        mbtnPress.setText((String) output);
                   }
                });

                asyncTask.execute(new Object[] { "Your request to aynchronous task class is giving here.." });


            }
        });

    }



}

Спасибо

Аршад
источник
17

Вы можете попробовать этот код в своем основном классе. Это сработало для меня, но я реализовал методы по-другому

try {
    String receivedData = new AsyncTask().execute("http://yourdomain.com/yourscript.php").get();
} 
catch (ExecutionException | InterruptedException ei) {
    ei.printStackTrace();
}
Нику П
источник
2
Не могли бы вы объяснить, почему это поможет ОП с их проблемой?
Джон Одом
3
Это помогло мне. Я попытался по-другому, как ответ от @HelmiB, но я не получил результатов
Nicu P
Хорошо, извините за мой ответ. Ей нужно вызвать класс AsyncTask, а затем поставить параметр для этого вызова. AsyncTask определяется 3 общими типами: 1 параметр (домен сервера или другой параметр) 2 прогресс (может быть недействительным), 3 результата. Все эти типы могут быть: JSONObject, или строки, или любые типы данных. Когда у вас есть класс AsyncTask, вы должны определить, куда отправлять данные. например: asyncTask.execute (" sampletargeturl.com"). get () ;
Нику П
При использовании этого метода я получил предупреждение в Logcat: «Я / Хореограф ipped Пропущено 50 кадров! Приложение может выполнять слишком много работы в своем основном потоке». Как с этим бороться? Получает ли пользовательский интерфейс зависание при ожидании возврата из AsyncTask?
Хай До
@NicuP Вы можете забыть позвонить execute(), посмотрите мой ответ, я добавил комментарий там. Вы можете проверить мой обновленный ответ. надеюсь это поможет.
HelmiB
16

Этот ответ может быть поздно, но я хотел бы упомянуть несколько вещей, когда вы Activityзависите AsyncTask. Это поможет вам предотвратить сбои и управление памятью. Как уже упоминалось в ответах выше interface, мы также называем их обратными вызовами. Они будут работать в качестве информатора, но никогда не будут посылать сильные ссылки Activityили interfaceвсегда будут использовать слабые ссылки в этих случаях.

Пожалуйста, обратитесь к скриншоту ниже, чтобы узнать, как это может вызвать проблемы.

введите описание изображения здесь

Как вы можете видеть, если мы начали AsyncTaskс сильной ссылки, то нет никакой гарантии, что наши Activity/ Fragmentбудут живы, пока мы не получим данные, поэтому было бы лучше использовать WeakReferenceв этих случаях, и это также поможет в управлении памятью, поскольку мы никогда не будем держать сильная ссылка нашего Activityтогда будет иметь право на сборку мусора после его искажения.

Ниже приведен фрагмент кода, чтобы узнать, как использовать классную WeakReference.

MyTaskInformer.java Интерфейс, который будет работать как информер.

public interface MyTaskInformer {

    void onTaskDone(String output);

}

MySmallAsyncTask.javaAsyncTask для выполнения длительной задачи, которую будет использовать WeakReference.

public class MySmallAsyncTask extends AsyncTask<String, Void, String> {

    // ***** Hold weak reference *****
    private WeakReference<MyTaskInformer> mCallBack;

    public MySmallAsyncTask(MyTaskInformer callback) {
        this.mCallBack = new WeakReference<>(callback);
    }

    @Override
    protected String doInBackground(String... params) {

        // Here do whatever your task is like reading/writing file
        // or read data from your server or any other heavy task

        // Let us suppose here you get response, just return it
        final String output = "Any out, mine is just demo output";

        // Return it from here to post execute
        return output;
    }

    @Override
    protected void onPostExecute(String s) {
        super.onPostExecute(s);

        // Here you can't guarantee that Activity/Fragment is alive who started this AsyncTask

        // Make sure your caller is active

        final MyTaskInformer callBack = mCallBack.get();

        if(callBack != null) {
            callBack.onTaskDone(s);
        }
    }
}

MainActivity.javaЭтот класс используется для запуска моей AsyncTaskреализации interfaceэтого класса и overrideэтого обязательного метода.

public class MainActivity extends Activity implements MyTaskInformer {

    private TextView mMyTextView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mMyTextView = (TextView) findViewById(R.id.tv_text_view);

        // Start your AsyncTask and pass reference of MyTaskInformer in constructor
        new MySmallAsyncTask(this).execute();
    }

    @Override
    public void onTaskDone(String output) {

        // Here you will receive output only if your Activity is alive.
        // no need to add checks like if(!isFinishing())

        mMyTextView.setText(output);
    }
}
Рахул
источник
2
Это замечательно! важный момент, который не может быть замечен.
Хаш
6

в вашем Oncreate ():

`

myTask.execute("url");
String result = "";
try {
      result = myTask.get().toString();
} catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
}catch (ExecutionException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();

} `

user3691697
источник
6

Вы можете сделать это в несколько строк, просто переопределите onPostExecute при вызове AsyncTask. Вот пример для вас:

new AasyncTask()
{
    @Override public void onPostExecute(String result)
    {
       // do whatever you want with result 
    }
}.execute(a.targetServer);

Я надеюсь, что это помогло вам, счастливой кодировки :)

Аяз Алифов
источник
Это не работает для меня. Это просто не входит в onPostExecuteметод.
Франсиско Ромеро,
4

Почему люди делают это так сложно.

Этого должно быть достаточно.

Не реализуйте onPostExecute в асинхронной задаче, а реализуйте его в Activity:

public class MainActivity extends Activity 
{

@Override
public void onCreate(Bundle savedInstanceState) {

    //execute the async task 
    MyAsyncTask task = new MyAsyncTask(){
            protected void onPostExecute(String result) {
                //Do your thing
            }       

    }

    task.execute("Param");

}


}
bugdayci
источник
Это работает для меня. Это просто и легко понять. Я думаю, что он использует то, для чего предназначен Java. Спасибо. PS: нужно ли добавлять @Override?
Старый Geezer
1
Нет. @Override - это просто аннотация. Итак, вы сообщаете Java-компилятору, что вы собираетесь переопределить метод и получить информацию, если вы этого не делаете.
bugdayci
4

Вы можете вызвать get()метод AsyncTask(или перегружен get(long, TimeUnit)). Этот метод будет блокировать до тех AsyncTaskпор, пока не завершит свою работу, после чего он вернет вам Result.

Было бы разумно выполнять другую работу между созданием / запуском вашей асинхронной задачи и вызовом getметода, иначе вы не очень эффективно используете асинхронную задачу.

nicholas.hauschild
источник
1
Понизившийся vecause get () заблокирует основной поток. Нет причин использовать AsyncTask, если он заблокирует
GabrielBB
3

Вы можете написать свой собственный слушатель. Это то же самое, что и ответ HelmiB , но выглядит более естественно:

Создать интерфейс слушателя:

public interface myAsyncTaskCompletedListener {
    void onMyAsynTaskCompleted(int responseCode, String result);
}

Затем напишите свою асинхронную задачу:

public class myAsyncTask extends AsyncTask<String, Void, String> {

    private myAsyncTaskCompletedListener listener;
    private int responseCode = 0;

    public myAsyncTask() {
    }

    public myAsyncTask(myAsyncTaskCompletedListener listener, int responseCode) {
        this.listener = listener;
        this.responseCode = responseCode;
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
    }


    @Override
    protected String doInBackground(String... params) {
        String result;
        String param = (params.length == 0) ? null : params[0];
        if (param != null) {
            // Do some background jobs, like httprequest...
            return result;
        }
        return null;
    }

    @Override
    protected void onPostExecute(String finalResult) {
        super.onPostExecute(finalResult);
        if (!isCancelled()) {
            if (listener != null) {
                listener.onMyAsynTaskCompleted(responseCode, finalResult);
            }
        }
    }
}

Наконец внедрите слушателя в действие:

public class MainActivity extends AppCompatActivity implements myAsyncTaskCompletedListener {

    @Override
    public void onMyAsynTaskCompleted(int responseCode, String result) {

        switch (responseCode) {
            case TASK_CODE_ONE: 
                // Do something for CODE_ONE
                break;
            case TASK_CODE_TWO:
                // Do something for CODE_TWO
                break;
            default: 
                // Show some error code
        }        
    }

И вот как вы можете вызвать asyncTask:

 protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // Some other codes...
        new myAsyncTask(this,TASK_CODE_ONE).execute("Data for background job");
        // And some another codes...
}
Kuvalya
источник
2

Привет, вы можете сделать что-то вроде этого:

  1. Создать класс, который реализует AsyncTask

    // TASK 
    public class SomeClass extends AsyncTask<Void, Void, String>>
    {
    
        private OnTaskExecutionFinished _task_finished_event;
    
        public interface OnTaskExecutionFinished
        {
            public void OnTaskFihishedEvent(String Reslut);
        }
    
        public void setOnTaskFinishedEvent(OnTaskExecutionFinished _event)
        {
            if(_event != null)
            {
                this._task_finished_event = _event;
            }
        }
    
        @Override
        protected void onPreExecute()
        {
            super.onPreExecute();
    
        }
    
        @Override
        protected String doInBackground(Void... params)
        {
            // do your background task here ...
    
            return "Done!";
        }
    
        @Override
        protected void onPostExecute(String result)
        {
            super.onPostExecute(result);
            if(this._task_finished_event != null)
            {
                this._task_finished_event.OnTaskFihishedEvent(result);
            }
            else
            {
                Log.d("SomeClass", "task_finished even is null");
            }
        }
    }
  2. Добавить в основной активности

    // MAIN ACTIVITY
    public class MyActivity extends ListActivity
    {
       ...
        SomeClass _some_class = new SomeClass();
        _someclass.setOnTaskFinishedEvent(new _some_class.OnTaskExecutionFinished()
        {
        @Override
        public void OnTaskFihishedEvent(String result)
        {
            Toast.makeText(getApplicationContext(),
                    "Phony thread finished: " + result,
                    Toast.LENGTH_SHORT).show();
        }
    
       });
       _some_class.execute();
       ...
     }
Олег Карбушев
источник
1

Создайте статический член в вашем классе Activity. Затем назначьте значение во времяonPostExecute

Например, если результатом вашего AsyncTask является String, создайте открытую статическую строку в вашем Activity

public static String dataFromAsyncTask;

Затем, в onPostExecuteAsyncTask, просто сделайте статический вызов вашему основному классу и установите значение.

MainActivity.dataFromAsyncTask = "result blah";

mrres1
источник
1
Каковы возможности утечки памяти в этом сценарии?
антроид
0

Я делаю это с помощью потоков и обработчика / сообщения. Шаги следующим образом: объявить диалог

ProgressDialog loadingdialog;

Создайте функцию, чтобы закрыть диалог после завершения операции.

   private Handler handler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        loadingdialog.dismiss();

    }
    };

Код вашей детализации:

 public void startUpload(String filepath) {
    loadingdialog = ProgressDialog.show(MainActivity.this, "Uploading", "Uploading Please Wait", true);
    final String _path = filepath;
    new Thread() {
        public void run() {
            try {
                UploadFile(_path, getHostName(), getPortNo());
                handler.sendEmptyMessage(0);

            } catch (Exception e) {
                Log.e("threadmessage", e.getMessage());
            }
        }
    }.start();
}
RAY
источник
0

Вам необходимо использовать «протоколы» для делегирования или предоставления данных AsynTask.

Делегаты и источники данных

Делегат - это объект, который действует от имени или в координации с другим объектом, когда этот объект встречает событие в программе. ( Определение Apple )

протоколы - это интерфейсы, которые определяют некоторые методы для делегирования некоторых типов поведения.

Вот полный пример !!!

IgniteCoders
источник
0

попробуй это:

public class SomAsyncTask extends AsyncTask<String, Integer, JSONObject> {

    private CallBack callBack;

    public interface CallBack {
        void async( JSONObject jsonResult );
        void sync( JSONObject jsonResult );
        void progress( Integer... status );
        void cancel();
    }

    public SomAsyncTask(CallBack callBack) {
        this.callBack = callBack;
    }

    @Override
    protected JSONObject doInBackground(String... strings) {

        JSONObject dataJson = null;

        //TODO query, get some dataJson

        if(this.callBack != null)
            this.callBack.async( dataJson );// asynchronize with MAIN LOOP THREAD

        return dataJson;

    }

    @Override
    protected void onProgressUpdate(Integer... values) {
        super.onProgressUpdate(values);

        if(this.callBack != null)
            this.callBack.progress(values);// synchronize with MAIN LOOP THREAD

    }

    @Override
    protected void onPostExecute(JSONObject jsonObject) {
        super.onPostExecute(jsonObject);

        if(this.callBack != null)
            this.callBack.sync(jsonObject);// synchronize with MAIN LOOP THREAD
    }

    @Override
    protected void onCancelled() {
        super.onCancelled();

        if(this.callBack != null)
            this.callBack.cancel();

    }
}

И пример использования:

public void onCreate(@Nullable Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);

         final Context _localContext = getContext();
         SomeAsyncTask.CallBack someCallBack = new SomeAsyncTask.CallBack() {

                @Override
                public void async(JSONObject jsonResult) {//async thread
                    //some async process, e.g. send data to server...
                }

                @Override
                public void sync(JSONObject jsonResult) {//sync thread
                    //get result...

                    //get some resource of Activity variable...
                    Resources resources = _localContext.getResources();
                }

                @Override
                public void progress(Integer... status) {//sync thread
                    //e.g. change status progress bar...
                }

                @Override
                public void cancel() {

                }

            };

            new SomeAsyncTask( someCallBack )
                                .execute("someParams0", "someParams1", "someParams2");

    }
amiron
источник
0

Возможно, немного перегружен, но я предоставил обратные вызовы как для кода выполнения, так и для результатов. очевидно, для безопасности потоков вы хотите быть осторожными с тем, к чему вы обращаетесь при выполнении обратного вызова

Реализация AsyncTask:

public class AsyncDbCall<ExecuteType,ResultType> extends AsyncTask<ExecuteType, Void,  
ResultType>
{
    public interface ExecuteCallback<E, R>
    {
        public R execute(E executeInput);
    }
    public interface PostExecuteCallback<R>
    {
        public void finish(R result);
    }

    private PostExecuteCallback<ResultType> _resultCallback = null;
    private ExecuteCallback<ExecuteType,ResultType> _executeCallback = null;


    AsyncDbCall(ExecuteCallback<ExecuteType,ResultType> executeCallback, PostExecuteCallback<ResultType> postExecuteCallback)
    {
        _resultCallback = postExecuteCallback;
        _executeCallback = executeCallback;
    }

    AsyncDbCall(ExecuteCallback<ExecuteType,ResultType> executeCallback)
    {
        _executeCallback = executeCallback;
    }

    @Override
    protected ResultType doInBackground(final ExecuteType... params)
    {
        return  _executeCallback.execute(params[0]);
    }

    @Override
    protected void onPostExecute(ResultType result)
    {
        if(_resultCallback != null)
            _resultCallback.finish(result);
    }
}

Обратный звонок:

 AsyncDbCall.ExecuteCallback<Device, Device> updateDeviceCallback = new 
 AsyncDbCall.ExecuteCallback<Device, Device>()
    {
        @Override
        public Device execute(Device device)
        {
            deviceDao.updateDevice(device);
            return device;
        }
    };

И, наконец, выполнение асинхронной задачи:

 new AsyncDbCall<>(addDeviceCallback, resultCallback).execute(device);
Squibly
источник
0

Надеюсь, что вы прошли через это , если нет, пожалуйста, прочитайте.

https://developer.android.com/reference/android/os/AsyncTask

В зависимости от характера данных результатов, вы должны выбрать наилучший из возможных вариантов.

Это отличный выбор для использования интерфейса

некоторые другие варианты будут ..

  • Если класс AsyncTask определен внутри самого класса, в котором вы хотите использовать результат, в. Используйте статическую глобальную переменную или get () , используйте его из внешнего класса ( при необходимости переменная переменная ). но он должен знать о прогрессе AsyncTask или, по крайней мере, должен убедиться, что он завершил задачу, и результат доступен через метод глобальной переменной / get (). Вы можете использовать опрос, onProgressUpdate (Progress ...) , синхронизацию или интерфейсы (которые когда-либо подходят вам лучше всего)

  • Если результат совместим быть записью sharedPreference или это нормально быть сохранено в виде файла в памяти можно сохранить даже от самой фоновой задачи и может использовать onPostExecute () метод ,
    чтобы получить уведомление , когда результат доступен в память.

  • Если строка достаточно мала и должна использоваться с началом действия. в onPostExecute () можно использовать намерения ( putExtra () ) , но помните, что с статическими контекстами работать не так безопасно .

  • Если возможно, вы можете вызывать статический метод из метода onPostExecute (), а результатом будет ваш параметр

жесткий
источник