Пример AsyncTask для Android
Я читал о AsyncTask
, и я попробовал простую программу ниже. Но это не похоже на работу. Как я могу заставить это работать?
package com.test;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.Settings.System;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.view.View.OnClickListener;
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>
16 ответов
Хорошо, вы пытаетесь получить доступ к GUI через другой поток. Это, в основном, не очень хорошая практика.
AsyncTask выполняет все в doInBackground()
внутри другого потока, который не имеет доступа к GUI, где находятся ваши представления.
preExecute()
а также postExecute()
предложить вам доступ к графическому интерфейсу до и после того, как в этом новом потоке возникнет тяжелая работа, вы даже можете передать результат длительной операции postExecute()
чтобы потом показать какие-либо результаты обработки.
Посмотрите эти строки, где вы позже обновляете свой TextView:
TextView txt = (TextView) findViewById(R.id.output);
txt.setText("Executed");
положить их в PostExecute()
После этого вы увидите текст TextView, обновленный после doInBackground
завершается.
РЕДАКТИРОВАТЬ: я заметил, что ваш слушатель onClick не проверяет, какой вид был выбран. Я считаю, что самый простой способ сделать это с помощью операторов switch. У меня есть полный класс, отредактированный ниже со всеми предложениями, чтобы избежать путаницы.
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.Settings.System;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.view.View.OnClickListener;
public class AsyncTaskActivity extends Activity implements OnClickListener {
Button btn;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btn = (Button) findViewById(R.id.button1);
// because we implement OnClickListener we only have to pass "this"
// (much easier)
btn.setOnClickListener(this);
}
public void onClick(View view) {
// detect the view that was "clicked"
switch (view.getId()) {
case R.id.button1:
new LongOperation().execute("");
break;
}
}
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) {
Thread.interrupted();
}
}
return "Executed";
}
@Override
protected void onPostExecute(String result) {
TextView txt = (TextView) findViewById(R.id.output);
txt.setText("Executed"); // txt.setText(result);
// might want to change "executed" for the returned string passed
// into onPostExecute() but that is upto you
}
@Override
protected void onPreExecute() {}
@Override
protected void onProgressUpdate(Void... values) {}
}
}
Мой полный ответ здесь, но вот пояснительное изображение, чтобы дополнить другие ответы на этой странице. Для меня понимание того, куда идут все переменные, было самой запутанной частью в начале.
Я уверен, что он работает правильно, но вы пытаетесь изменить элементы пользовательского интерфейса в фоновом потоке, и это не сработает.
Пересмотрите свой вызов и AsyncTask следующим образом:
Вызывая класс
Примечание: я лично предлагаю использовать onPostExecute()
где бы вы ни выполняли свой поток AsyncTask, а не в классе, который расширяет сам AsyncTask. Я думаю, что это облегчает чтение кода, особенно если вам нужен AsyncTask в нескольких местах, где результаты немного отличаются.
new LongThread()
{
@Override public void onPostExecute(String result)
{
TextView txt = (TextView) findViewById(R.id.output);
txt.setText(result);
}
}.execute("");
Класс LongThread (расширяет AsyncTask):
@Override
protected String doInBackground(String... params) {
for(int i = 0; i < 5; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return "Executed";
}
Я создал простой пример использования AsyncTask для Android. Начинается с onPreExecute(), doInBackground(), publishProgress()
и наконец onProgressUpdate()
,
В этом doInBackground() работает как фоновый поток, в то время как другие работают в потоке пользовательского интерфейса. Вы не можете получить доступ к элементу пользовательского интерфейса в doInBackground(). Последовательность такая же, как я уже упоминал.
Однако, если вам нужно обновить любой виджет из doInBackground
вы можете publishProgress
от doInBackground
который позвонит onProgressUpdate
обновить свой виджет пользовательского интерфейса.
class TestAsync extends AsyncTask<Void, Integer, String>
{
String TAG = getClass().getSimpleName();
protected void onPreExecute (){
super.onPreExecute();
Log.d(TAG + " PreExceute","On pre Exceute......");
}
protected String doInBackground(Void...arg0) {
Log.d(TAG + " DoINBackGround","On doInBackground...");
for(int i=0; i<10; i++){
Integer in = new Integer(i);
publishProgress(i);
}
return "You are at PostExecute";
}
protected void onProgressUpdate(Integer...a){
super.onProgressUpdate(a);
Log.d(TAG + " onProgressUpdate", "You are in progress update ... " + a[0]);
}
protected void onPostExecute(String result) {
super.onPostExecute(result);
Log.d(TAG + " onPostExecute", "" + result);
}
}
Называйте это так в своей деятельности:
new TestAsync().execute();
Переместите эти две строки:
TextView txt = (TextView) findViewById(R.id.output);
txt.setText("Executed");
из вашей AsyncTask's doInBackground
метод и положить их в onPostExecute
метод. Ваш AsyncTask
должен выглядеть примерно так:
private class LongOperation extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... params) {
try {
Thread.sleep(5000); // no need for a loop
} catch (InterruptedException e) {
Log.e("LongOperation", "Interrupted", e);
return "Interrupted";
}
return "Executed";
}
@Override
protected void onPostExecute(String result) {
TextView txt = (TextView) findViewById(R.id.output);
txt.setText(result);
}
}
Как запомнить параметры, используемые в AsyncTask?
не
Если вы новичок в AsyncTask, то очень часто можно запутаться при написании AsyncTask. Основными виновниками являются параметры, используемые в AsyncTask, т.е. AsyncTask<A,B,C>
, Основанный на A,B,C (аргументы) сигнатура методов отличается, что делает вещь еще более запутанной.
Будь проще!
Ключ не запоминай. Если вы можете визуализировать, что на самом деле нужно делать вашей задаче, то написание AsyncTask с правильной подписью с первой попытки было бы просто. Просто выясните, каковы ваши входные данные, прогресс и выход, и вам будет хорошо идти.
Так что же такое AsyncTask?
AsyncTask - это фоновая задача, которая запускается в фоновом потоке. Он принимает входные данные, выполняет прогресс и выдает выходные данные.
т.е.
AsyncTask<Input,Progress,Output>
,
Например:
Какая связь с методами?
Между
AsyncTask
а такжеdoInBackground()
doInBackground()
а такжеonPostExecute(),
onProgressUpdate()`также связаны
Как написать это в коде?
DownloadTask extends AsyncTask<String,Integer,String>{
// Always same signature
@Override
public void onPreExecute()
{}
@Override
public String doInbackGround(String... params)
{
// Download code
int downloadPerc = // calculate that
publish(downloadPerc);
return "Download Success";
}
@Override
public void onPostExecute(String result)
{
super.onPostExecute(result);
}
@Override
public void onProgressUpdate(Integer... params)
{
// show in spinner, access UI elements
}
}
Как вы будете выполнять эту задачу?
new DownLoadTask().execute("Paradise.mp3");
Фон / Теория
AsyncTask позволяет запускать задачу в фоновом потоке, одновременно публикуя результаты в потоке пользовательского интерфейса.
Пользователь всегда должен иметь возможность взаимодействовать с приложением, поэтому важно избегать блокировки основного потока (UI) такими задачами, как загрузка контента из Интернета.
Вот почему мы используем
AsyncTask
,Он предлагает простой интерфейс, заключая в себе очередь сообщений потока UI и обработчик, который позволяет отправлять и обрабатывать выполняемые объекты и сообщения из других потоков.
Реализация
AsyncTask является универсальным классом. (Он принимает параметризованные типы в своем конструкторе.)
Он использует эти три универсальных типа:
Params
- тип параметров, отправляемых заданию при выполнении.
Progress
- тип единиц прогресса, опубликованных во время фонового вычисления.
Result
- тип результата фонового вычисления.
Не все типы всегда используются асинхронной задачей. Чтобы пометить тип как неиспользуемый, просто используйте тип Void:
private class MyTask extends AsyncTask<Void, Void, Void> { ... }
Эти три параметра соответствуют трем основным функциям, которые вы можете переопределить в AsyncTask
:
doInBackground(Params...)
onProgressUpdate(Progress...)
onPostExecute(Result)
Выполнить AsyncTask
вызов execute()
с параметрами для отправки в фоновую задачу.
Что просходит
На основной / пользовательский интерфейс потока,
onPreExecute()
называется. (Для инициализации чего-либо в этом потоке, например отображения индикатора выполнения в пользовательском интерфейсе.)В фоновом потоке,
doInBackground(Params...)
называется. (Параметры передаются в функцию Execute.)Где должна выполняться долгосрочная задача
Должен переопределить хотя бы
doInBackground()
использовать AsyncTask.Вызов
publishProgress(Progress...)
обновить отображение прогресса в пользовательском интерфейсе, пока выполняется фоновое вычисление. (Например, анимировать индикатор выполнения или показать журналы в текстовом поле.)- Это вызывает
onProgressUpdate()
быть названным.
- Это вызывает
В фоновом потоке результат возвращается из
doInBackground()
, Это запускает следующий шаг.На основной / пользовательский интерфейс потока,
onPostExecute()
Вызван с возвращенным результатом.
Примеры
Повторно используя пример задачи блокировки, состоящей в том, чтобы загрузить что-то из Интернета,
- Пример A загружает изображение и отображает его в ImageView,
- в то время как пример B загружает некоторые файлы.
Пример А
doInBackground()
Метод загружает изображение и сохраняет его в объекте типа BitMap. onPostExecute()
Метод берет растровое изображение и помещает его в ImageView.
class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
ImageView bitImage;
public DownloadImageTask(ImageView bitImage) {
this.bitImage = bitImage;
}
protected Bitmap doInBackground(String... urls) {
String urldisplay = urls[0];
Bitmap mBmp = null;
try {
InputStream in = new java.net.URL(urldisplay).openStream();
mBmp = BitmapFactory.decodeStream(in);
} catch (Exception e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return mBmp;
}
protected void onPostExecute(Bitmap result) {
bitImage.setImageBitmap(result);
}
}
Пример Б
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
protected Long doInBackground(URL... urls) {
int count = urls.length;
long totalSize = 0;
for (int i = 0; i < count; i++) {
totalSize += Downloader.downloadFile(urls[i]);
publishProgress((int) ((i / (float) count) * 100));
// Escape early if cancel() is called
if (isCancelled()) break;
}
return totalSize;
}
protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}
protected void onPostExecute(Long result) {
showDialog("Downloaded " + result + " bytes");
}
}
Пример Б исполнения
new DownloadFilesTask().execute(url1, url2, url3);
Когда асинхронная задача выполняется, задача проходит 4 шага:
- onPreExecute ()
- doInBackground (Params...)
- onProgressUpdate (Прогресс...)
- onPostExecute (Результат)
Ниже приведен демонстрационный пример
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
protected Long doInBackground(URL... urls) {
int count = urls.length;
long totalSize = 0;
for (int i = 0; i < count; i++) {
totalSize += Downloader.downloadFile(urls[i]);
publishProgress((int) ((i / (float) count) * 100));
// Escape early if cancel() is called
if (isCancelled()) break;
}
return totalSize;
}
protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}
protected void onPostExecute(Long result) {
showDialog("Downloaded " + result + " bytes");
}
}
и как только вы создали, задача выполняется очень просто:
new DownloadFilesTask().execute(url1, url2, url3);
Я надеюсь, что это поможет вам...
Кратчайший пример просто что-то делать асинхронно:
class MyAsyncTask extends android.os.AsyncTask {
@Override
protected Object doInBackground(Object[] objects) {
//do something asynchronously
return null;
}
}
Чтобы запустить это:
(new MyAsyncTask()).execute();
Когда вы находитесь в рабочем потоке, вы не можете напрямую манипулировать элементами пользовательского интерфейса на Android.
Когда вы используете AsyncTask, пожалуйста, поймите методы обратного вызова.
Например:
public class MyAyncTask extends AsyncTask<Void, Void, Void>{
@Override
protected void onPreExecute() {
// Here you can show progress bar or something on the similar lines.
// Since you are in a UI thread here.
super.onPreExecute();
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
// After completing execution of given task, control will return here.
// Hence if you want to populate UI elements with fetched data, do it here.
}
@Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
// You can track you progress update here
}
@Override
protected Void doInBackground(Void... params) {
// Here you are in the worker thread and you are not allowed to access UI thread from here.
// Here you can perform network operations or any heavy operations you want.
return null;
}
}
К сведению: чтобы получить доступ к потоку пользовательского интерфейса из рабочего потока, используйте либо метод runOnUiThread(), либо метод post в своем представлении.
Например:
runOnUiThread(new Runnable() {
textView.setText("something.");
});
or
yourview.post(new Runnable() {
yourview.setText("something");
});
Это поможет вам лучше узнать вещи. Следовательно, в вашем случае вам нужно установить текстовое представление в методе onPostExecute().
Я бы рекомендовал сделать вашу жизнь проще, используя эту библиотеку для фоновых работ https://github.com/Arasthel/AsyncJobLibrary
это так просто..
AsyncJob.doInBackground(new AsyncJob.OnBackgroundJob() {
@Override
public void doOnBackground() {
startRecording();
}
});
Подробное руководство по объяснению AsyncTask
Что такое AsyncTask?
AsyncTask - это класс Android, который помогает нам выполнять сложные операции, такие как
- Сетевые операции.
- Операции с базой данных.
- Хранение и чтение данных из больших текстовых файлов.
Это ослабляет напряжение разработчиков из
- Создание и прекращение потоков.
- UI поток синхронизации и управления.
если ты
- не знаю, сколько времени требуется для вашей задачи или задача занимает много времени
- Хотите выполнить бесконечный цикл работы.
AsyncTask не лучший вариант для вас. AsyncTask в основном используется для коротких операций (максимум несколько секунд)
Как использовать AsyncTask в вашем приложении?
- Создайте подкласс AsyncTask.
- Переопределите doInBackground() и другие методы.
- Создайте экземпляр подкласса AsyncTask и вызовите execute().
AsyncTask использует типы данных Generics
- Params - данные, используемые для запуска фонового потока.
- Ход выполнения - данные, которые используются для уведомления о ходе выполнения задачи.
- Результат - данные, которые возвращаются из doInBackground() после выполнения.
AsyncTask помогает нам обновлять интерфейс в рамках своих методов.
- onPreExecute ()
- onProgressUpdate ()
- onPostExecute ()
- onCancelled ()
Эти методы выполняются в главном потоке. Вот почему вы можете обновить элементы пользовательского интерфейса.
Добавьте вашу сложную задачу в doInBackgrund()
и вызовите AsyncTask, используя метод execute ().
Полная подробная учебная ссылка ниже
Пример асинхронной задачи с запросом POST:
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("key1", "value1"));
params.add(new BasicNameValuePair("key1", "value2"));
new WEBSERVICEREQUESTOR(URL, params).execute();
class WEBSERVICEREQUESTOR extends AsyncTask<String, Integer, String>
{
String URL;
List<NameValuePair> parameters;
private ProgressDialog pDialog;
public WEBSERVICEREQUESTOR(String url, List<NameValuePair> params)
{
this.URL = url;
this.parameters = params;
}
@Override
protected void onPreExecute()
{
pDialog = new ProgressDialog(LoginActivity.this);
pDialog.setMessage("Processing Request...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
super.onPreExecute();
}
@Override
protected String doInBackground(String... params)
{
try
{
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpEntity httpEntity = null;
HttpResponse httpResponse = null;
HttpPost httpPost = new HttpPost(URL);
if (parameters != null)
{
httpPost.setEntity(new UrlEncodedFormEntity(parameters));
}
httpResponse = httpClient.execute(httpPost);
httpEntity = httpResponse.getEntity();
return EntityUtils.toString(httpEntity);
} catch (Exception e)
{
}
return "";
}
@Override
protected void onPostExecute(String result)
{
pDialog.dismiss();
try
{
}
catch (Exception e)
{
}
super.onPostExecute(result);
}
}
Обновление: март 2020 г.
Согласно официальной документации разработчика Android, AsyncTask устарел.
Вместо этого рекомендуется использовать котлин-корурины. Проще говоря, это позволяет вам писать асинхронные задачи в последовательном стиле.
ASync Task;
public class MainActivity extends AppCompatActivity {
private String ApiUrl = "your_api";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MyTask myTask = new MyTask();
try {
String result=myTask.execute(ApiUrl).get();
Toast.makeText(getApplicationContext(), result, Toast.LENGTH_SHORT).show();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public class MyTask extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... strings) {
String result = "";
HttpURLConnection httpURLConnection = null;
URL url;
try {
url = new URL(strings[0]);
httpURLConnection = (HttpURLConnection) url.openConnection();
InputStream inputStream = httpURLConnection.getInputStream();
InputStreamReader reader = new InputStreamReader(inputStream);
result = getData(reader);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
public String getData(InputStreamReader reader) throws IOException {
String result = "";
int data = reader.read();
while (data!=-1) {
char now = (char) data;
result += data;
data = reader.read();
}
return result;
}
}
}
При работе с AsyncTask необходимо создать класс-наследник и в нем прописать реализацию необходимых нам методов. В этом уроке мы рассмотрим три метода:
doInBackground - будет выполняться в новом потоке, и здесь мы решаем все свои непростые задачи. Потому что неосновной поток не имеет доступа к пользовательскому интерфейсу.
onPreExecute - выполняется до doInBackground и имеет доступ к пользовательскому интерфейсу
onPostExecute - выполняется после doInBackground (не работает, если AsyncTask был отменен - об этом в следующих уроках) и имеет доступ к UI.
Это класс MyAsyncTask:
class MyAsyncTask extends AsyncTask<Void, Void, Void> {
@Override
protected void onPreExecute() {
super.onPreExecute();
tvInfo.setText("Start");
}
@Override
protected Void doInBackground(Void... params) {
// Your background method
return null;
}
@Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
tvInfo.setText("Finish");
}
}
И вот как вызвать свою активность или фрагмент:
MyAsyncTask myAsyncTask = new MyAsyncTask();
myAsyncTask.execute();
Вам нужно объявить кнопку onclicklistener, после нажатия на нее вызывается класс AsyncTask DownloadJson, процесс будет показан ниже:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btn = (Button) findViewById(R.id.button1);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new DownloadJson().execute();
}
});
}
// DownloadJSON AsyncTask
private class DownloadJson extends AsyncTask<Void, Void, Void> {
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected Void doInBackground(Void... params) {
newlist = new ArrayList<HashMap<String, String>>();
json = jsonParser.makeHttpRequest(json, "POST");
try {
newarray = new JSONArray(json);
for (int i = 0; i < countdisplay; i++) {
HashMap<String, String> eachnew = new HashMap<String, String>();
newobject = newarray.getJSONObject(i);
eachnew.put("id", newobject.getString("ID"));
eachnew.put("name", newobject.getString("Name"));
newlist.add(eachnew);
}
}
} catch (JSONException e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(Void args) {
newlisttemp.addAll(newlist);
NewAdapterpager newadapterpager = new NewAdapterpager(ProcesssActivitypager.this,newlisttemp);
newpager.setAdapter(newadapterpager);
}
}
private class AsyncTaskDemo extends AsyncTask<Void, Void, Void> {
@Override
protected void onPreExecute() {
super.onPreExecute();
// Showing progress dialog
progressDialog = new ProgressDialog(this);
progressDialog.setMessage("Loading...");
progressDialog.setCancelable(false);
progressDialog.show();
}
@Override
protected Void doInBackground(Void... arg0) {
//do code here
return null;
}
@Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
// Dismiss the progress dialog
if (progressDialog.isShowing()) {
progressDialog.dismiss();
}
}
@Override
protected void onCancelled() {
super.onCancelled();
progressDialog.dismiss();
Toast toast = Toast.makeText(getActivity(),
"Error is occured due to some probelm", Toast.LENGTH_LONG);
toast.setGravity(Gravity.TOP, 25, 400);
toast.show();
}
}
Просто:
LongOperation MyTask = new LongOperation();
MyTask.execute();
Если вы откроете класс AsyncTask, вы увидите код ниже.
public abstract class AsyncTask<Params, Progress, Result> {
@WorkerThread
protected abstract Result doInBackground(Params... params);
@MainThread
protected void onPreExecute() {
}
@SuppressWarnings({"UnusedDeclaration"})
@MainThread
protected void onPostExecute(Result result) {
}
}
Возможности AsyncTask
- AsyncTask - абстрактный класс
- AsyncTask имеет 3 общих параметра.
- AsyncTask имеет абстрактный метод doInBackground, onPreExecute, onPostExecute
- doInBackground - это WorkerThread (вы не можете обновить пользовательский интерфейс)
- onPreExecute - это MainThread
- onPostExecute - это MainThread (вы можете обновить пользовательский интерфейс)
пример
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
mEmailView = (AutoCompleteTextView) findViewById(R.id.email);
AsyncTask<Void, Void, Post> asyncTask = new AsyncTask<Void, Void, Post>() {
@Override
protected Post doInBackground(Void... params) {
try {
ApiClient defaultClient = Configuration.getDefaultApiClient();
String authorization = "eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxLCJleHAiOjE1ODIxMzM4MTB9.bA3Byc_SuB6jzqUGAY4Pyt4oBNg0VfDRctZ8-PcPlYg"; // String | JWT token for Authorization
ApiKeyAuth Bearer = (ApiKeyAuth) defaultClient.getAuthentication("Bearer");
Bearer.setApiKey(authorization);
PostApi apiInstance = new PostApi();
String id = "1"; // String | id
Integer commentPage = 1; // Integer | Page number for Comment
Integer commentPer = 10; // Integer | Per page number For Comment
Post result;
try {
result = apiInstance.apiV1PostsIdGet(id, authorization, commentPage, commentPer);
} catch (ApiException e) {
e.printStackTrace();
result = new Post();
}
return result;
} catch (Exception e) {
e.printStackTrace();
return new Post();
}
}
@Override
protected void onPostExecute(Post post) {
super.onPostExecute(post);
if (post != null) {
mEmailView.setText(post.getBody());
System.out.print(post);
}
}
};
asyncTask.execute();
}
Пример AsyncTask с прогрессом
import android.animation.ObjectAnimator;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.LinearInterpolator;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
public class AsyncTaskActivity extends AppCompatActivity implements View.OnClickListener {
Button btn;
ProgressBar progressBar;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn = (Button) findViewById(R.id.button1);
btn.setOnClickListener(this);
progressBar = (ProgressBar)findViewById(R.id.pbar);
}
public void onClick(View view) {
switch (view.getId()) {
case R.id.button1:
new LongOperation().execute("");
break;
}
}
private class LongOperation extends AsyncTask<String, Integer, String> {
@Override
protected String doInBackground(String... params) {
Log.d("AsyncTask", "doInBackground");
for (int i = 0; i < 5; i++) {
try {
Log.d("AsyncTask", "task "+(i + 1));
publishProgress(i + 1);
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.interrupted();
}
}
return "Completed";
}
@Override
protected void onPostExecute(String result) {
Log.d("AsyncTask", "onPostExecute");
TextView txt = (TextView) findViewById(R.id.output);
txt.setText(result);
progressBar.setProgress(0);
}
@Override
protected void onPreExecute() {
Log.d("AsyncTask", "onPreExecute");
TextView txt = (TextView) findViewById(R.id.output);
txt.setText("onPreExecute");
progressBar.setMax(500);
progressBar.setProgress(0);
}
@Override
protected void onProgressUpdate(Integer... values) {
Log.d("AsyncTask", "onProgressUpdate "+values[0]);
TextView txt = (TextView) findViewById(R.id.output);
txt.setText("onProgressUpdate "+values[0]);
ObjectAnimator animation = ObjectAnimator.ofInt(progressBar, "progress", 100 * values[0]);
animation.setDuration(1000);
animation.setInterpolator(new LinearInterpolator());
animation.start();
}
}
}
Измените свой код, как указано ниже:
@Override
protected void onPostExecute(String result) {
runOnUiThread(new Runnable() {
public void run() {
TextView txt = (TextView) findViewById(R.id.output);
txt.setText("Executed");
}
});
}