Я читал о AsyncTask
, и я попробовал простую программу ниже. Но это не похоже на работу. Как я могу заставить это работать?
public class AsyncTaskActivity extends Activity {
Button btn;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btn = (Button) findViewById(R.id.button1);
btn.setOnClickListener((OnClickListener) this);
}
public void onClick(View view){
new LongOperation().execute("");
}
private class LongOperation extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... params) {
for(int i=0;i<5;i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
TextView txt = (TextView) findViewById(R.id.output);
txt.setText("Executed");
return null;
}
@Override
protected void onPostExecute(String result) {
}
@Override
protected void onPreExecute() {
}
@Override
protected void onProgressUpdate(Void... values) {
}
}
}
Я просто пытаюсь изменить метку через 5 секунд в фоновом режиме.
Это мой main.xml :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<ProgressBar
android:id="@+id/progressBar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:indeterminate="false"
android:max="10"
android:padding="10dip">
</ProgressBar>
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Start Progress" >
</Button>
<TextView android:id="@+id/output"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Replace"/>
</LinearLayout>
Ответы:
Хорошо, вы пытаетесь получить доступ к GUI через другой поток. Это, в основном, не очень хорошая практика.
AsyncTask выполняет все
doInBackground()
внутри другого потока, который не имеет доступа к GUI, где находятся ваши представления.preExecute()
иpostExecute()
предложить вам доступ к GUI до и после того, как в этом новом потоке возникнет тяжелый подъем, и вы даже можете передать результат длительной операции,postExecute()
чтобы затем показать какие-либо результаты обработки.Посмотрите эти строки, где вы позже обновляете свой TextView:
Поместите их
onPostExecute()
.После этого вы увидите текст TextView, обновленный после
doInBackground
завершения.Я заметил, что ваш слушатель onClick не проверяет, какой вид был выбран. Я считаю, что самый простой способ сделать это с помощью операторов switch. У меня есть полный класс, отредактированный ниже со всеми предложениями, чтобы избежать путаницы.
источник
onPostExecute(String result)
метода. Для будущих читателей будет понятнее, что аргумент заполняется возвращаемым значениемdoInBackground(String... params)
.Мой полный ответ здесь , но вот пояснительное изображение, чтобы дополнить другие ответы на этой странице. Для меня понимание того, куда идут все переменные, было самой запутанной частью в начале.
источник
params
это массив. (В приведенном выше примере это былString
массив.) Это позволяет передавать несколько параметров одного типа. Тогда вы можете получить доступ к этим параметрам сparams[0]
,params[1]
,params[2]
и т.д. В примере, был только одинString
вparams
массиве. Если вам нужно передать несколько параметров разных типов (например, aString
и anint
), посмотрите этот вопрос .Я уверен, что он работает правильно, но вы пытаетесь изменить элементы пользовательского интерфейса в фоновом потоке, и это не сработает.
Измените ваш вызов и AsyncTask следующим образом:
Вызывая класс
Примечание: я лично предлагаю использовать
onPostExecute()
везде, где вы выполняете свой поток AsyncTask, а не в классе, который расширяет сам AsyncTask. Я думаю, что это облегчает чтение кода, особенно если вам нужен AsyncTask в нескольких местах, где результаты немного отличаются.Класс LongThread (расширяет AsyncTask):
источник
onPostExecute
в деятельности блестяще.Я создал простой пример использования AsyncTask для Android. Начинается с
onPreExecute(), doInBackground(), publishProgress()
и наконецonProgressUpdate()
.В этом doInBackground () работает как фоновый поток, в то время как другие работают в потоке пользовательского интерфейса. Вы не можете получить доступ к элементу пользовательского интерфейса в doInBackground (). Последовательность такая же, как я уже упоминал.
Однако, если вам нужно обновить какой-либо виджет из
doInBackground
, вы можетеpublishProgress
изdoInBackground
которого позвоните,onProgressUpdate
чтобы обновить ваш виджет пользовательского интерфейса.Называйте это так в своей деятельности:
Справочник разработчика здесь
источник
Переместите эти две строки:
из метода AsyncTask
doInBackground
и поместите их вonPostExecute
метод. ВыAsyncTask
должны выглядеть примерно так:источник
AsyncTask
, на которые отвечает мой ответ; и отправка значения из службы в поток пользовательского интерфейса, который рассматривается другим обсуждением. Эти вопросы независимы.Фон / Теория
AsyncTask позволяет запускать задачу в фоновом потоке, одновременно публикуя результаты в потоке пользовательского интерфейса.
Реализация
AsyncTask является универсальным классом. (Он принимает параметризованные типы в своем конструкторе.)
Он использует эти три универсальных типа:
Params
- тип параметров, отправляемых заданию при выполнении.Progress
- тип единиц прогресса, опубликованных во время фонового вычисления.Result
- тип результата фонового вычисления.Эти три параметра соответствуют трем основным функциям, которые вы можете переопределить
AsyncTask
:doInBackground(Params...)
onProgressUpdate(Progress...)
onPostExecute(Result)
Выполнить AsyncTask
execute()
с параметрами для отправки в фоновую задачу.Что просходит
На главном потоке / UI ,
onPreExecute()
называется.На фоне темы ,
doInBackground(Params...)
называется.Params
были переданы черезexecute
.)Необходимо переопределить хотя бы
doInBackground()
для использования AsyncTask.Вызовите,
publishProgress(Progress...)
чтобы обновить пользовательский интерфейс с отображением прогресса (например, анимация пользовательского интерфейса или напечатанный текст журнала), пока вычисление фона все еще выполняется.onProgressUpdate()
для вызова.В фоновом потоке результат возвращается из
doInBackground()
.На главном потоке / UI ,
onPostExecute()
вызываются с возвращенным результатом.Примеры
В обоих примерах «задача блокировки» - это загрузка из Интернета.
Пример А
doInBackground()
Метод загружает изображение и сохраняет его в объекте типа Bitmap.onPostExecute()
Метод принимает растровое изображение и помещает его в ImageView.Пример Б
Пример Б исполнения
источник
Когда асинхронная задача выполняется, задача проходит четыре этапа:
Ниже приведен демонстрационный пример:
И как только вы создали, задача выполняется очень просто:
источник
Кратчайший пример просто что-то делать асинхронно:
Чтобы запустить это:
источник
Как запомнить параметры, используемые в AsyncTask?
Если вы новичок в AsyncTask, то очень часто можно запутаться при написании AsyncTask. Основными виновниками являются параметры , используемые в AsyncTask, то есть
AsyncTask<A, B, C>
. На основании A, B, C (аргументы) сигнатура методов отличается, что делает вещи еще более запутанными.Будь проще!
Ключ не запоминай . Если вы можете визуализировать, что на самом деле нужно сделать вашей задаче, то написание AsyncTask с правильной подписью с первой попытки было бы просто. Просто выясни, что у тебя
Input
,Progress
иOutput
есть, и тебе будет хорошо идти.Так что же такое AsyncTask?
AsyncTask - это фоновая задача, которая запускается в фоновом потоке. Он берет
Input
, выполняетProgress
и даетOutput
.Например:
Какая связь с методами?
Как написать это в коде?
Как вы будете выполнять эту задачу?
источник
Когда вы находитесь в рабочем потоке, вы не можете напрямую манипулировать элементами пользовательского интерфейса на Android.
Когда вы используете AsyncTask, пожалуйста, поймите методы обратного вызова.
Например:
К сведению: чтобы получить доступ к потоку пользовательского интерфейса из рабочего потока, вы либо используете метод runOnUiThread () или метод post в своем представлении.
Например:
Это поможет вам лучше узнать вещи. Следовательно, в вашем случае вам нужно установить текстовое представление в методе onPostExecute ().
источник
Я бы порекомендовал сделать вашу жизнь проще, используя эту библиотеку для фоновых работ:
https://github.com/Arasthel/AsyncJobLibrary
Это так просто ...
источник
Пример асинхронной задачи с запросом POST:
источник
Просто:
источник
Вам необходимо объявить кнопку включения кликера. После нажатия вызывается класс AsyncTask DownloadJson.
Процесс будет показан ниже:
источник
источник
Обновление: март 2020
Согласно официальной документации разработчика Android , AsyncTask устарела.
Вместо этого рекомендуется использовать котлин корорины . Просто он позволяет вам писать асинхронные задачи в последовательном стиле.
источник
Пример AsyncTask с прогрессом
источник
ASync Task;
источник
MyTask
внутри классаMainActivity
? Это принято?При работе с AsyncTask необходимо создать класс-наследник и в нем зарегистрировать реализацию необходимых нам методов. В этом уроке мы рассмотрим три метода:
doInBackground - будет выполнен в новом потоке, и здесь мы решаем все наши сложные задачи. Потому что неосновной поток не имеет доступа к пользовательскому интерфейсу.
onPreExecute - выполняется до doInBackground и имеет доступ к пользовательскому интерфейсу
onPostExecute - выполняется после doInBackground (не работает, если AsyncTask был отменен - об этом в следующих уроках) и имеет доступ к пользовательскому интерфейсу.
Это класс MyAsyncTask:
И вот как позвонить в вашей деятельности или фрагмент:
источник
если вы откроете класс AsyncTask, вы увидите код ниже.
Особенности AsyncTask
пример
источник
Измените свой код, как указано ниже:
источник