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

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

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

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

4 ответа

Решение

Вы можете создать 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 не дает результат 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;


    }

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

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

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

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

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 и передайте его асинхронной задаче. Вот пример:

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

Готово!

Другие вопросы по тегам