2013-03-18 2 views
11

Я играл с различными примерами, пытаясь ознакомиться с AsyncTask. До сих пор все примеры, которые я видел, имели AsyncTask, включенные в метод onCreate основной активности. Который мне не очень нравится, поэтому я хотел увидеть, как трудно было бы разделить его на свой класс. До сих пор у меня есть это:Разработка Android: наличие AsyncTask в отдельном файле класса

Основная деятельность

package com.example.asynctaskactivity; 

import android.os.AsyncTask; 
import android.os.Bundle; 
import android.os.SystemClock; 
import android.app.Activity; 
import android.util.Log; 
import android.view.View; 
import android.widget.Button; 
import android.widget.ProgressBar; 
import android.widget.TextView; 
import android.widget.Toast; 

import com.example.asynctaskactivity.ShowDialogAsyncTask; 

public class AsyncTaskActivity extends Activity { 

Button btn_start; 
ProgressBar progressBar; 
TextView txt_percentage; 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 

     btn_start = (Button) findViewById(R.id.btn_start); 
     progressBar = (ProgressBar) findViewById(R.id.progress); 
     txt_percentage= (TextView) findViewById(R.id.txt_percentage); 
     Log.v("onCreate","Attempt set up button OnClickListener"); 
     btn_start.setOnClickListener(new View.OnClickListener() 
     { 
      @Override 
      public void onClick(View v) { 
       btn_start.setEnabled(false); 
       new ShowDialogAsyncTask().execute(); 
      } 
     }); 

     Log.v("onCreate","Success!"); 
    } 
} 

новый индивидуальный класс AsyncTask

package com.example.asynctaskactivity; 

import android.os.AsyncTask; 
import android.os.SystemClock; 
import android.util.Log; 
import android.widget.Button; 
import android.widget.ProgressBar; 
import android.widget.TextView; 
import android.widget.Toast; 

public class ShowDialogAsyncTask extends AsyncTask<Void, Integer, Void>{ 
int progress_status; 

@Override 
    protected void onPreExecute() { 
    // update the UI immediately after the task is executed 
    Log.v("onPreExecute","1"); 
    super.onPreExecute(); 
    Log.v("onPreExecute","2"); 
    //Toast.makeText(AsyncTaskActivity.this,"Invoke onPreExecute()", Toast.LENGTH_SHORT).show(); 
    progress_status = 0; 
    Log.v("onPreExecute","3"); 
    txt_percentage.setText("downloading 0%"); 
    Log.v("onPreExecute","4"); 
    } 

    @Override 
    protected Void doInBackground(Void... params) { 
     Log.v("doInBackground","1"); 
     while(progress_status<100){ 

      progress_status += 2; 

      publishProgress(progress_status); 
      SystemClock.sleep(300); 

     } 
     return null; 
    } 

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

    progressBar.setProgress(values[0]); 
    txt_percentage.setText("downloading " +values[0]+"%"); 
    } 

    @Override 
    protected void onPostExecute(Void result) { 
    super.onPostExecute(result); 

    //Toast.makeText(AsyncTaskActivity.this,"Invoke onPostExecute()", Toast.LENGTH_SHORT).show(); 

    txt_percentage.setText("download complete"); 
    btn_start.setEnabled(true); 
    } 
} 

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

Извините, если это глупый вопрос, совершенно новый для разработки Android и фоновых потоков в частности.

+0

Выглядит очень похоже на http: // stackoverflow.com/questions/6119305/android-how-to-run-asynctask-from-different-class-file – user2070018

+1

В качестве побочного кода вам не нужно вызывать супер методы в 'AsyncTask', они ничего не делают. – nhaarman

+0

В чем их смысл на самом деле, я заметил их во многих примерах asynctasks, на которые я смотрел, и не мог понять их цель. – cosmicsafari

ответ

17

Как можно разделить файл, но все еще обновлять поток пользовательского интерфейса.

Okey. Поэтому сначала вы знаете, что основное преимущество AsyncTask, добавленное в Activity как внутренний класс, заключается в том, что у вас есть прямой доступ ко всем элементам пользовательского интерфейса, и это делает возможным «легкий» пользовательский интерфейс.

Но если вы решили сделать AsyncTask отделено от деятельности (которые также имеют некоторые преимущества, эквалайзер код более чистый и приложение логик отделен от внешнего вида) класс вы можете:

  • Вы можете передать элементы пользовательского интерфейса с помощью конструктора от класса
  • Вы можете создавать различные сеттеры
  • Вы можете создать интерфейс, который будет содержать обратные вызовы. Посмотрите на Android AsyncTask sending Callbacks to UI

Это все, что вам нужно, я думаю.

8

Добавить интерфейс обратного вызова, и пусть ваш Activity реализует его.

public interface MyAsyncTaskCallback{ 
    public void onAsyncTaskComplete(); 
} 

В postexecute:

myAsyncTaskCallback.onAsyncTaskComplete(); 

В конструкторе AsyncTask можно передать экземпляр MyAsyncTaskCallback (ваш Activity).

1

Ваш лучший способ справиться с этим через обработчик. Выполните одно из действий в операции и переопределите метод handleMessage(). Когда вы создаете класс ShowDialogAsyncTask, просто проходите в обработчике и поддерживайте ссылку на него. В postExecute вы можете создать сообщение и отправить его через метод обработчика sendMessage(). Прошлый ответ упоминается с использованием интерфейса и парадигмы обратного вызова. Это будет работать, однако существует вероятность того, что действие может быть уничтожено и не будет присутствовать при выполнении метода postExecute, поэтому вам нужно будет проверить это.

Смежные вопросы