Общий класс AsyncTask для Android
Я видел этот ответ:
Как получить результат OnPostExecute() для основной активности, потому что AsyncTask - это отдельный класс?
Но это не то, что я прошу, поскольку мой вызывающий класс имеет несколько вызовов для AsyncTask
.
Я хочу создать общий AsyncTask
класс, который будет принимать URL-адрес и загружать контент из заданного URL-адреса и возвращать загруженный контент.
Пример:
public class MyAsyncTask extends AsyncTask<String, Void, String>{
ProgressDialog dialog;
protected void onPreExecute() {
super.onPreExecute();
dialog = ProgressDialog.show(context, "Loading", "Please wait...", true);
}
protected String doInBackground(String... params) {
// do download here
}
protected void onPostExecute(String result) {
super.onPostExecute(result);
dialog.dismiss();
}
}
И у меня есть другой класс, который вызывает этот AsyncTask
в разных сценариях
public class MyClass {
public method1(String url) {
String result = new MyAsyncTask().execute(url).get();
}
public method2(String url) {
String result = new MyAsyncTask().execute(url).get();
}
}
Я знаю, что использование метода get()
сделает весь этот процесс задачей синхронизации. Но я хочу вернуть результат в вызывающий класс. И я также знаю, чтобы предотвратить это, я должен реализовать интерфейс. Но поскольку у меня есть несколько вызовов в одном классе, это невозможно. Так может ли кто-нибудь дать мне идею решить эту проблему?
Ответы
Ответ 1
Поскольку doInBackground
работает в фоновом режиме, вы не можете получить результат в нем, возвращая значение при вызове из активности.
Вам нужно установить обратный вызов, который будет вызван с результатом.
Для ex:
interface Callback{
void onResult(String result);
}
Сделайте свою деятельность реализацией этого и в действии
void onResult(String result){
//Do something
}
Теперь измените ваш asyncTask на:
public class MyAsyncTask extends AsyncTask<String, Void, String>{
ProgressDialog dialog;
Callback callback;
public MyAsyncTask(Callback callback){
this.callback=callback;
}
protected void onPreExecute() {
super.onPreExecute();
dialog = ProgressDialog.show(context, "Loading", "Please wait...", true);
}
protected String doInBackground(String... params) {
//do download here
}
protected void onPostExecute(String result) {
super.onPostExecute(result);
callback.onResult(result);
dialog.dismiss();
}
}
Во время запуска этой задачи из действия:
new MyAsyncTask(new Callback{
void onResult(String result){
//Do something
}
}).execute(url);
Поэтому, когда вы получите ответ onResult
, вызывается
Ответ 2
Почему несколько вызовов в одном классе нарушают интерфейс?
class Task extends AsyncTask{
public interface TaskDoneListener{
public void onDone(String result);
}
private TaskDoneListener listener;
public Task(TaskDoneListener list){
super();
listener = list;
}
public void onPostExecute(String result){
listener.onDone(result);
}
}
Ответ 3
Я предлагаю вам создать класс abstract
для этого:
public abstract class AsyncDownloader extends AsyncTask<...> {
doInBackground(Params...){
return doNetworkDownload();
}
ABSTRACK onPostExecute(Result);// Notice there no method body
}
Затем в любой из ваших действий, где задача загрузки одинакова, но разбор отличается, расширьте этот класс:
public class MainActivityAsyncTask extends AsyncDownloader {
//It will give you error, that you must implement the onPostExecute method at first
@Override
onPostExecute(Result){
doUiStuff();
}
}
Ответ 4
В вашем классе переопределите onPostExecute
, чтобы вернуть результат в ваш класс.
MyAsyncTask mytask = new MyAsyncTask(){
@Override
protected void onPostExecute(String result) {
//your code
}
}
mytask.execute(url);
Ответ 5
Вам нужно будет сделать интерфейс и в этом интерфейсе добавить один метод, имеющий тип аргумента, который вы хотите вернуть из AsyncTask.
и в конструкторе ссылки интерфейса интерфейса AsyncTask из вашей активности. и установить данные в интерфейсном методе из onPostExecute().
поэтому вы будете уведомлены в классе активности, если данные установлены из метода onPostExecute.
следуйте этому приятному ответу fooobar.com/info/9511/...