Android asynctask для отправки обратных вызовов в ui

У меня есть следующий класс asynctask, который не находится внутри операции. В этой операции я инициализирую асинтезу, и я хочу, чтобы асинтекс сообщал обратные вызовы к моей активности. Является ли это возможным? Или асинхронность должна быть в том же файле класса, что и активность?

protected void onProgressUpdate(Integer... values) { super.onProgressUpdate(values); caller.sometextfield.setText("bla"); } 

Что-то вроде этого?

Вы можете создать interface , передать его AsyncTask (в конструкторе), а затем вызвать метод в onPostExecute()

Например:

Ваш интерфейс:

 public interface OnTaskCompleted{ void onTaskCompleted(); } 

Ваша деятельность:

 public class YourActivity implements OnTaskCompleted{ // your Activity } 

И ваш AsyncTask:

 public class YourTask extends AsyncTask<Object,Object,Object>{ //change Object to required type private OnTaskCompleted listener; public YourTask(OnTaskCompleted listener){ this.listener=listener; } // required methods protected void onPostExecute(Object o){ // your stuff listener.onTaskCompleted(); } } 

РЕДАКТИРОВАТЬ

Поскольку этот ответ получил довольно популярный, я хочу добавить некоторые вещи.

Если вы новичок в разработке Android, AsyncTask – это быстрый способ заставить все работать, не блокируя поток пользовательского интерфейса. Это действительно решает некоторые проблемы, нет ничего плохого в том, как класс работает сам. Однако это приводит к некоторым последствиям, таким как:

  • Возможность утечки памяти. Если вы сохраните ссылку на свою Activity , она останется в памяти даже после выхода пользователя из экрана (или поворота устройства).
  • AsyncTask не AsyncTask результат Activity если Activity уже была уничтожена. Вы должны добавить дополнительный код, чтобы управлять всем этим или выполнять операции дважды.
  • Сопряженный код, который делает все в Activity

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

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

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

 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[] { "Youe request to aynchronous task class is giving here.." }); } }); } } 

благодаря

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

  Main.FragmentCallback FC= new Main.FragmentCallback(){ @Override public void onTaskDone(String results) { localText.setText(results); //example TextView } }; new API_CALL(this.getApplicationContext(), "GET",FC).execute("&Books=" + Main.Books + "&args=" + profile_id); 

Напомним: я использовал интерфейс для основной деятельности, где «Main» приходит, например:

 public interface FragmentCallback { public void onTaskDone(String results); } 

Выполнение моего API-сообщения выглядит следующим образом:

  @Override protected void onPostExecute(String results) { Log.i("TASK Result", results); mFragmentCallback.onTaskDone(results); } 

Конструктор API выглядит так:

  class API_CALL extends AsyncTask<String,Void,String> { private Main.FragmentCallback mFragmentCallback; private Context act; private String method; public API_CALL(Context ctx, String api_method,Main.FragmentCallback fragmentCallback) { act=ctx; method=api_method; mFragmentCallback = fragmentCallback; } 

Я повторю то, что говорили другие, но просто попытаюсь сделать это проще …

Во-первых, просто создайте класс интерфейса

 public interface PostTaskListener<K> { // K is the type of the result object of the async task void onPostTask(K result); } 

Во-вторых, создайте AsyncTask (который может быть внутренним статическим классом вашей активности или фрагмента), который использует интерфейс, путем включения конкретного класса. В примере PostTaskListener параметризуется String, что означает, что он ожидает класс String в результате задачи async.

 public static class LoadData extends AsyncTask<Void, Void, String> { private PostTaskListener<String> postTaskListener; protected LoadData(PostTaskListener<String> postTaskListener){ this.postTaskListener = postTaskListener; } @Override protected void onPostExecute(String result) { super.onPostExecute(result); if (result != null && postTaskListener != null) postTaskListener.onPostTask(result); } } 

Наконец, часть, где вы комбинируете свою логику. В своей деятельности / фрагменте создайте PostTaskListener и передайте его в async-задачу. Вот пример:

 ... PostTaskListener<String> postTaskListener = new PostTaskListener<String>() { @Override public void onPostTask(String result) { //Your post execution task code } } // Create the async task and pass it the post task listener. new LoadData(postTaskListener); 

Готово!