Як отримати результат OnPostExecute () до основної діяльності, оскільки AsyncTask - це окремий клас?


361

У мене це два класи. Моя основна діяльність і той , який розширює 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, або ви можете створити локальний приймач трансляції. Зразок реалізації реципієнта
Bikesh M

Чому б не використовувати шаблон спостерігача?
JAAAY

Відповіді:


750

Легко:

  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 . FYI, ви можете поєднати це в 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();

 }

Або знову реалізувати інтерфейс на Активність

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на різні типи відповідності, щоб отримати різні об'єкти.


20
Загалом все це написав, а потім побачив свою відповідь :) Ось так і думати! +1. Також таким чином багато речей можуть слухати результати AsyncTask!
Roloc

8
Я отримую nullpointer виняток, оскільки делегат встановлений на нуль, будь ласка,
очистіть

2
Лише зауваження для розробників .net, для цього можна використовувати AutoResetEvents, а також існує реалізація Java для авторесетевантов, але це набагато чистіше. До речі, чи безпечна нитка ProcessFinish?
Силер

13
для всіх, хто отримує нульовий покажчик, передайте інтерфейс вашому конструктору класу asyncTask, а потім призначте його змінній, а потім викликайте processfinish () на цій змінній. Для довідки див. Прийняте як відповідне. stackoverflow.com/questions/9963691/…
Сонячно,

2
@Sunny ви праві ... також ми повинні ініціалізувати об'єкт async для async.delegate = це; на роботу ..
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
        ...
    }

У другому варіанті: навіщо йти через біль конструктора і поля, якщо класу немає 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
Утримування посилання на активність також є витоком пам'яті. Підхід зворотного дзвінка набагато кращий за цей
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 () ;
Nicu P

Під час використання цього методу я отримав попередження на Logcat: "Я / хореограф ﹕ пропустив 50 кадрів! Додаток може робити надто багато роботи над його основною темою." Як з цим боротися? Чи отримує інтерфейс заморожування під час очікування повернення з AsyncTask?
Huy Do

@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
Це чудово! важливий момент, який не можна помітити.
HasH

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

} `


6

Ви можете зробити це в декілька рядків, просто перекрийте onPostExecute, коли ви викликаєте AsyncTask. Ось приклад для вас:

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

Я сподіваюся, що це допомогло вам, щасливе кодування :)


Це не працює для мене. Він просто не входить у onPostExecuteметод.
Франсіско Ромеро

4

Чому люди роблять це так важко.

Цього має бути достатньо.

Не реалізовуйте onPostExecute в задачі асинхронізації, а скоріше впроваджуйте його в Діяльності:

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

}


}

Це працює для мене. Це просте і найлегше зрозуміти. Я думаю, що він використовує те, що створено для Java. Дякую. PS: Чи потрібно додати @Override?
Old Geezer

1
Ні. @ Override - це лише примітка. Таким чином, ви говорите компілятору java, що ви маєте намір перекрити метод і отримати інформацію, якщо цього не зробите.
bugdayci

4

Ви можете викликати get()метод AsyncTask(або перевантажений get(long, TimeUnit)). Цей метод блокуватиметься до тих пір, поки функція AsyncTaskне завершить свою роботу, і після цього він поверне вамResult .

Було б розумно виконувати іншу роботу між створенням / початком завдання async та викликом getметоду, інакше ви не дуже ефективно використовуєте завдання async.


1
Неприхильний vease 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...
}

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

Створіть статичного члена у вашому класі активності. Потім призначте значення під часonPostExecute

Наприклад, якщо результатом AsyncTask є рядок, створіть загальну статичну рядок у своїй діяльності

public static String dataFromAsyncTask;

Потім у програмі onPostExecuteAsyncTask просто зробіть статичний дзвінок до вашого основного класу та встановіть значення.

MainActivity.dataFromAsyncTask = "result blah";


1
які можливості витоку пам'яті в цьому сценарії?
antroid

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

0

Вам потрібно використовувати "протоколи" для делегування або надання даних AsynTask.

Делегати та джерела даних

Делегат - це об'єкт, який діє від імені або узгоджується з іншим об'єктом, коли цей об’єкт стикається з подією в програмі. ( Визначення Apple )

протоколи - це інтерфейси, які визначають деякі методи делегування певної поведінки.

Ось повний приклад !!!


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

    }

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

І нарешті виконання завдання async:

 new AsyncDbCall<>(addDeviceCallback, resultCallback).execute(device);

0

Сподіваюся, ви пережили це , якщо не читайте.

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

Залежно від характеру даних результатів, слід вибрати найкращий варіант, про який ви можете придумати.

Це прекрасний вибір для використання інтерфейсу

деякі інші варіанти будуть ..

  • Якщо клас AsyncTask визначений всередині самого класу, для якого потрібно використовувати результат. Використовуйте статичну глобальну змінну або get () , використовуйте її з зовнішнього класу ( при необхідності мінливої ​​змінної ). але слід знати про прогрес AsyncTask або, принаймні, переконайтесь, що він закінчив завдання, а результат доступний за допомогою глобального методу змінної / get (). ви можете використовувати опитування, onProgressUpdate (Прогрес ...) , синхронізацію чи інтерфейси (що коли-небудь підходить для вас)

  • Якщо Результат сумісний із записом sharedPreference або добре зберігати його як файл у пам'яті, ви можете зберегти його навіть із самого фонового завдання та застосувати метод onPostExecute (),
    щоб отримувати повідомлення, коли результат доступний у пам'ять.

  • Якщо рядок досить малий, і його потрібно використовувати для початку діяльності. можна використовувати наміри ( putExtra () ) в onPostExecute () , але пам’ятайте, що статичні контексти не так безпечні для вирішення.

  • Якщо можливо, ви можете викликати статичний метод з методу onPostExecute (), результатом якого є ваш параметр

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.