Термин «контекст» иногда используется для ссылки на объект, на который ссылается this . Его использование неуместно, потому что оно не подходит ни семантически, ни технически с помощью ECMAScript в этом .
«Контекст» означает обстоятельства, окружающие что-то, что добавляет смысл , или некоторая предшествующая и следующая информация, которая дает дополнительный смысл. Термин «контекст» используется в ECMAScript для ссылки на контекст выполнения , который является всеми параметрами, областью действия и этой в рамках некоторого исполняемого кода.
Это показано в разделе 10.4.2 ECMA-262 :
Установите значение ThisBinding на то же значение, что и ThisBinding для контекста выполнения вызова
, в котором четко указано, что этот является частью контекста выполнения.
Контекст выполнения предоставляет информацию, которая добавляет смысл в код, который выполняется , Он содержит гораздо больше информации о том, что только thisBinding .
Таким образом, значение этого не является «контекстом», это всего лишь одна часть выполнения контекст. Это, по сути, локальная переменная, которая может быть задана вызовом любого объекта и в строгом режиме для любого значения вообще.
Хорошо, вы пытаетесь получить доступ к графическому интерфейсу через другой поток. Это, в основном, не является хорошей практикой.
AsyncTask выполняет все в doInBackground()
внутри другого потока, который не имеет доступа к графическому интерфейсу, где ваши представления.
preExecute()
и postExecute()
предлагают вам доступ к графическому интерфейсу до и после тяжелого подъема в этом новом потоке, вы можете даже передать результат длинной операции postExecute()
, чтобы затем показать какие-либо результаты обработки.
См. эти строки, где вы позже обновив TextView:
TextView txt = (TextView) findViewById(R.id.output);
txt.setText("Executed");
поместите их в PostExecute()
После этого вы увидите текст TextView после завершения doInBackground
.
EDIT : Я заметил, что ваш слушатель 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 для 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();
Я уверен, что он выполняется правильно, но вы пытаетесь изменить элементы пользовательского интерфейса в фоновом потоке, и это не будет сделано.
Пересмотрите свой вызов и 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";
}
params
- массив. (В приведенном выше примере это был массив String
.) Это позволяет вам передавать несколько параметров одного и того же типа. Затем вы можете получить доступ к этим параметрам с помощью params[0]
, params[1]
, params[2]
и т. Д. В примере в массиве params
был только один String
. Если вам нужно передать несколько параметров разных типов (например, String
и int
), см. этот вопрос .
– Suragch
2 February 2016 в 02:29
onPostExecute
в деятельности блестяще.
– mcy
25 May 2017 в 08:56
Вам нужно объявить кнопку 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);
}
}
Когда выполняется асинхронная задача, задача выполняет 4 этапа:
Ниже приведен демонстрационный пример
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);
Надеюсь, это поможет вам ...
Я бы рекомендовал облегчить вашу жизнь, используя эту библиотеку для фоновых работ https://github.com/Arasthel/AsyncJobLibrary
. Это просто ..
AsyncJob.doInBackground(new AsyncJob.OnBackgroundJob() {
@Override
public void doOnBackground() {
startRecording();
}
});
Измените свой код следующим образом:
@Override
protected void onPostExecute(String result) {
runOnUiThread(new Runnable() {
public void run() {
TextView txt = (TextView) findViewById(R.id.output);
txt.setText("Executed");
}
});
}
Переместите эти две строки:
TextView txt = (TextView) findViewById(R.id.output);
txt.setText("Executed");
из вашего метода doInBackground
AsyncTask и поместите их в метод 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
, на которые я отвечаю; и отправляет значение из службы в поток ui, к которому обращается другая дискуссия. Эти вопросы независимы.
– Ted Hopp
21 January 2015 в 21:25
AsyncTask позволяет запускать задачу в фоновом потоке при публикации результатов в потоке пользовательского интерфейса.
Пользователь всегда должен взаимодействовать с приложением, поэтому важно не блокировать основной поток (UI) такими задачами, как загрузка содержимого из Интернета.
Вот почему мы используем
AsyncTask
.Он предлагает простой интерфейс , обертывающий очередь сообщений и обработчик потока пользовательского интерфейса, которые позволяют отправлять и обрабатывать запущенные объекты и сообщения из других потоков .
blockquote>Реализация
AsyncTask - это общий класс. (Он принимает параметризованные типы в своем конструкторе.)
Он использует эти три общих типа:
Params
- тип параметров, отправленных в задачу после выполнения.
Progress
- тип единиц прогресса, опубликованных во время фонового вычисления.
Result
- тип результата фонового вычисления.] Не все типы всегда используются асинхронной задачей. Чтобы пометить тип как неиспользованный, просто используйте тип Void:
blockquote>
private class MyTask extends AsyncTask<Void, Void, Void> { ... }
Эти три параметра соответствуют трем основным функциям, которые вы можете переопределить в
AsyncTask
:
doInBackground(Params...)
onProgressUpdate(Progress...)
onPostExecute(Result)
Для выполнения AsyncTask
вызывать
execute()
с параметрами, которые будут отправлены в фоновое задание.Что происходит
- В главном / пользовательском потоке вызывается
onPreExecute()
. (Чтобы инициализировать что-то в этом потоке, например, показать индикатор выполнения в пользовательском интерфейсе.)- В фоновом потоке вызывается
doInBackground(Params...)
. (Параметры - это те, которые передаются функции Execute.) В тех случаях, когда должно выполняться многолетняя задача. Чтобы использовать AsyncTask, необходимо переопределить хотя быdoInBackground()
. ВызовитеpublishProgress(Progress...)
, чтобы обновить отображение прогресса в пользовательском интерфейсе, пока выполняется фоновое вычисление. (например, анимировать индикатор выполнения или показывать журналы в текстовом поле.) Это вызывает вызовonProgressUpdate()
.- В фоновом потоке результат возвращается из
doInBackground()
. Это приводит к следующему шагу.- В главном / пользовательском потоке,
onPostExecute()
вызывается с возвращенным результатом.Примеры
Используя снова Например, задача блокировки заключается в загрузке чего-либо из Интернета,
- Пример A загружает изображение и отображает его в ImageView,
- , в то время как в примере B загружаются некоторые файлы.
Пример A
Метод
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); } }
Пример B
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"); } }
Пример выполнения B
new DownloadFilesTask().execute(url1, url2, url3);
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();
}
}
Самый короткий пример для асинхронного выполнения:
class MyAsyncTask extends android.os.AsyncTask {
@Override
protected Object doInBackground(Object[] objects) {
//do something asynchronously
return null;
}
}
Чтобы запустить его:
(new MyAsyncTask()).execute();
onPostExecute(String result)
. Для будущих читателей было бы более ясно, что аргумент заполняется возвращаемым значениемdoInBackground(String... params)
. – Eric 28 December 2012 в 12:37