Android: Как я могу передать параметры в onPreExecute () AsyncTask?
я использую AsyncTask
для операций загрузки, которые я реализовал как внутренний класс.
на onPreExecute()
Я показываю диалог загрузки, который затем снова скрываю в onPostExecute()
. Но для некоторых операций загрузки я заранее знаю, что они закончатся очень быстро, поэтому я не хочу отображать диалоговое окно загрузки.
Я хотел указать это с помощью логического параметра, который я мог бы передать onPreExecute()
но, видимо, по какой-то причине onPreExecute()
нет параметры.
очевидным обходным путем, вероятно, было бы создание поля члена в моей AsyncTask или во внешнем классе, который я должен был бы установить перед каждой операцией загрузки, но это не кажется очень элегантным. Есть ли лучший способ сделать это?
4 ответа:
вы можете переопределить конструктор. Что-то вроде:
private class MyAsyncTask extends AsyncTask<Void, Void, Void> { public MyAsyncTask(boolean showLoading) { super(); // do stuff } // doInBackground() et al. }
затем, при вызове задачи, сделайте что-то вроде:
new MyAsyncTask(true).execute(maybe_other_params);
Edit: это более полезно, чем создание переменных-членов, поскольку упрощает вызов задачи. Сравните приведенный выше код с:
MyAsyncTask task = new MyAsyncTask(); task.showLoading = false; task.execute();
1) Для меня это самый простой способ передачи параметров для асинхронных задач вот так
// To call the async task do it like this Boolean[] myTaskParams = { true, true, true }; myAsyncTask = new myAsyncTask ().execute(myTaskParams);
объявить и использовать асинхронную задачу, как здесь
private class myAsyncTask extends AsyncTask<Boolean, Void, Void> { @Override protected Void doInBackground(Boolean...pParams) { Boolean param1, param2, param3; // param1=pParams[0]; param2=pParams[1]; param3=pParams[2]; .... }
2) Передача методов в async-task Для того, чтобы избежать кодирования асинхронных задач инфраструктуры (резьба, messagenhandler, ...) несколько раз вы можете рассмотреть возможность передачи методов, которые должны быть выполнены в вашей асинхронной задаче в качестве параметра. Следующий пример описывает этот подход. В кроме того, вам может потребоваться подкласс асинхронной задачи для передачи параметров инициализации в конструкторе.
/* Generic Async Task */ interface MyGenericMethod { int execute(String param); } protected class testtask extends AsyncTask<MyGenericMethod, Void, Void> { public String mParam; // member variable to parameterize the function @Override protected Void doInBackground(MyGenericMethod... params) { // do something here params[0].execute("Myparameter"); return null; } } // to start the asynctask do something like that public void startAsyncTask() { // AsyncTask<MyGenericMethod, Void, Void> mytest = new testtask().execute(new MyGenericMethod() { public int execute(String param) { //body return 1; } }); }
почему, как и какие параметры передаются в Asynctask, подробно посмотреть здесь. Я думаю, что это лучшее объяснение.
в документации Google для Android говорится, что:
асинхронная задача определяется 3 универсальными типами, называемыми Params, Progress и Result, и 4 шагами, называемыми onPreExecute, doInBackground, onProgressUpdate и onPostExecute.
общие типы AsyncTask:
три типа, используемые асинхронной задачей: следующее:
Params, тип параметров, отправляемых в задачу при выполнении. Прогресс, тип единиц прогресса, опубликованных во время фоновых вычислений. Результат, тип результата фоновой задачи. Не все типы всегда используются асинхронной задачи. Чтобы пометить тип как неиспользуемый, просто используйте тип Void:
private class MyTask extends AsyncTask<Void, Void, Void> { ... }
вы можете дополнительно обратиться : http://developer.android.com/reference/android/os/AsyncTask.html
или вы можете прояснить, какова роль AsyncTask, ссылаясь на блог Санкар-Ганеша
ну структура типичного класса AsyncTask выглядит так:
private class MyTask extends AsyncTask<X, Y, Z> protected void onPreExecute(){ }
этот метод выполняется перед запуском нового потока. Там нет входных / выходных значений, так что просто инициализировать переменные или все, что вы думаете, что вам нужно сделать.
protected Z doInBackground(X...x){ }
самый важный метод в Класс AsyncTask. Вы должны разместить здесь все, что вы хотите сделать в фоновом режиме, в другом потоке от основного. Здесь мы имеем в качестве входного значения массив объектов из типа " X " (вы видите в заголовке? У нас есть "...расширяет AsyncTask " это типы входных параметров) и возвращает объект из типа "Z".
protected void onProgressUpdate (Y y){
} Этот метод вызывается с помощью метода publishProgress (y) и обычно используется если вы хотите показать какой-либо прогресс или информацию на главном экране, например, индикатор выполнения, показывающий ход выполнения операции, которую вы делаете в фоновом режиме.
protected void onPostExecute (Z z){
} Этот метод вызывается после выполнения операции в фоновом режиме. В качестве входного параметра вы получите выходной параметр метода doInBackground.
как насчет типов X, Y и Z?
как вы можете сделать вывод из вышеизложенного структура:
X – The type of the input variables value you want to set to the background process. This can be an array of objects. Y – The type of the objects you are going to enter in the onProgressUpdate method. Z – The type of the result from the operations you have done in the background process.
как мы называем эту задачу из внешнего класса? Только со следующими двумя строками:
MyTask myTask = new MyTask(); myTask.execute(x);
где x-входной параметр типа X.
как только мы запустим нашу задачу, мы сможем узнать ее статус "снаружи". Используя метод " getStatus ()".
myTask.метод getstatus(); и мы можем получить следующий статус:
RUNNING-указывает, что задача выполняется.
ожидание - указывает что задача еще не выполнена.
готово-указывает, что onPostExecute(Z) закончил.
подсказки об использовании AsyncTask
не вызывайте методы onPreExecute, doInBackground и onPostExecute вручную. Это автоматически делается системой.
вы не можете вызвать AsyncTask внутри другой AsyncTask или Thread. Вызов метода execute должен быть выполнен в потоке пользовательского интерфейса.
выполняется метод onPostExecute в потоке пользовательского интерфейса (здесь вы можете вызвать другую AsyncTask!).
входные параметры задачи могут быть массивом объектов, таким образом, вы можете поместить любые объекты и типы, которые вы хотите.
вы можете либо передать параметр в конструкторе задач, либо при вызове execute:
AsyncTask<Object, Void, MyTaskResult>
первый параметр (объект) передается в doInBackground. Третий параметр (MyTaskResult) возвращается doInBackground. Вы можете изменить их на типы, которые вы хотите. Три точки означают, что ноль или более объектов (или массив из них) могут быть переданы в качестве аргумента(ов).
public class MyActivity extends AppCompatActivity { TextView textView1; TextView textView2; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main2); textView1 = (TextView) findViewById(R.id.textView1); textView2 = (TextView) findViewById(R.id.textView2); String input1 = "test"; boolean input2 = true; int input3 = 100; long input4 = 100000000; new MyTask(input3, input4).execute(input1, input2); } private class MyTaskResult { String text1; String text2; } private class MyTask extends AsyncTask<Object, Void, MyTaskResult> { private String val1; private boolean val2; private int val3; private long val4; public MyTask(int in3, long in4) { this.val3 = in3; this.val4 = in4; // Do something ... } protected void onPreExecute() { // Do something ... } @Override protected MyTaskResult doInBackground(Object... params) { MyTaskResult res = new MyTaskResult(); val1 = (String) params[0]; val2 = (boolean) params[1]; //Do some lengthy operation res.text1 = RunProc1(val1); res.text2 = RunProc2(val2); return res; } @Override protected void onPostExecute(MyTaskResult res) { textView1.setText(res.text1); textView2.setText(res.text2); } } }