Asyntask: почему обновление UI Thread в doInbackground встретит ошибку?

Когда я читаю документ об asyntask , они говорят, что: «не следует» обновлять поток пользовательского интерфейса в doInbackground, потому что doInbackground работает в разных потоках.

Это означает: это действие будет опасно, потому что поток пользовательского интерфейса не является потокобезопасным. Я понимаю. Но когда я пытаюсь проверить, что произойдет, когда я обновляю поток пользовательского интерфейса в этой функции. Я получаю сообщение об ошибке: (но ошибка не выглядит так, потому что aysnchonize , а потому, что мы НЕ МОЖЕМ сделать это)

  (TextView)((Activity)context).findViewById(R.id.text)).setText("StackOverFlow"); //context: reference of context object of UI Thread 

Пожалуйста, объясните мне. Разве мы shouldn't mustn't или mustn't .

благодаря 🙂

То, что я понял до сих пор с Android, есть …,

Мы не можем обновить поток пользовательского интерфейса из фонового потока. Может быть, это так, что они заставили нас обновить интерфейс из фонового потока.

Причина этого очень ясна … @ OS уровень будет так много потоков будет работать.

А также другой поток из разных приложений , и в этом случае на экране будет хаос, если мы сможем обновить UI из bg-thread

Внутри doInBackground вы не получите доступ к пользовательскому интерфейсу. Если вы хотите использовать UI-доступ publishProgress от doInBackground, вы перейдете на onProgressUpdate, чтобы сделать то, что вы хотите показать в пользовательском интерфейсе.

Ниже приведен код, который вы проверите для справки:

Класс DownloadAsyncTask расширяет AsyncTask {

  ProgressDialog progressDialog; @Override protected void onPreExecute() { super.onPreExecute(); progressDialog = ProgressDialog.show(Login.this, "", "Please Wait ..."); } @Override protected Void doInBackground(String... arg0) { int status1 = validationuser(username); Log.i("MyLog", "Inside the doInBackground is came"+status1); if(status1 == 1) { publishProgress(status1+ "Valid User Code","1",""+status1); } else { publishProgress(status1+ " Invalid Valid User Code","0",""+status1); } return null; } @Override protected void onProgressUpdate(String...values){ super.onProgressUpdate(values); int index = Integer.parseInt(values[2]); if(index == 1) { USERIDLOGIN = edittextuserName.getText().toString(); Intent intent=new Intent(Login.this, CollectionModuleandDownload.class); /*Toast.makeText(Login.this, "Valid User Password", Toast.LENGTH_SHORT).show();*/ startActivity(intent); progressDialog.dismiss(); } else { Toast.makeText(Login.this, "Invalid Username & Password", Toast.LENGTH_SHORT).show(); progressDialog.dismiss(); } } @Override protected void onPostExecute(Void result){ super.onPostExecute(result); /*if(progressDialog != null) { progressDialog.dismiss(); }*/ } } 

Поэтому вам нужно обновить ui только на OnPostExecute & OnPreExecute. Вот хороший пример asynctask. Попробуйте

Вы называете это

 new SaveProfile().execute(); 

То это …

 private class SaveProfile extends AsyncTask<String, Void, Boolean>{ @Override protected Boolean doInBackground(String... params) { //---------- so your stuff here.... non ui related Log.v("response from saving",response); if(response.equals("1")){ return true; }else{ return false; } } protected void onPostExecute(Boolean result) { if(result) { //------ UPDATE UI HERE Toast.makeText(ProfileCompanyActivity.this, "profile saved", 2500).show(); }else{ Toast.makeText(ProfileCompanyActivity.this, "an error occured", 2500).show(); } } } 

Когда вы создаете задачу doInBackground метод doInBackground запускается в отдельном потоке из потока пользовательского интерфейса. Таким образом, вы не можете обновить пользовательский интерфейс из этого метода.

Метод OnPostExecute и onPreExecute выполняется в том же потоке, что и поток пользовательского интерфейса. Для дальнейшего чтения перейдите сюда

Если только один поток может касаться пользовательского интерфейса, Android может гарантировать, что ничего существенного не будет изменено, пока оно будет измерять виды и отображать их на экране. Это потому, что .. Пользовательский интерфейс может быть обновлен только на mainthread..все объекты пользовательского интерфейса На вашем экране поддерживается этот mainthread …. теперь, если вы попытаетесь изменить пользовательский интерфейс из какого-то другого потока (сделайте это в фоновом режиме) в этом случае .. он вызывает ошибку, потому что … например, если вы попытаетесь изменить (Некоторые виджеты) значение из другого, чем основной поток .. и пользователь пытается поставить другое значение … то это неоднозначно для android .. что касается того, какой поток он должен слушать … надеюсь, что он уточняет ваши сомнения ..

Итак, это похоже на то, что мы не должны пытаться .. и из-за его безопасности .. мы также не можем попробовать .. как это дает ошибка .. =]

DoInBackground используется для выполнения тяжелых вычислений или любых фоновых работ, которые вы хотите выполнять в своей деятельности. Когда операция в вашем методе doinbackground закончена, на постэкскурентных методах upadates ваш ui .. Короче doinbackground не используется для обновления ui.

Я думаю, что ответ заключается в том, что мы не должны

Мне это просто не кажется логичным … как будто он пытается изменить радиостанцию ​​на другой машине, ведущей рядом с вами. Архитектура просто не работает. Вы можете выбрать радиостанцию, прежде чем отправиться в Ваше путешествие по дороге или когда вы прекратите вождение, и теоретически вы можете орать ему и попросить его сменить станцию, но вы не можете сделать это сами.

Поскольку doInBackground () работает в отдельном потоке, а onPostExecute работает в потоке UIMain, и в соответствии с ограничениями, предоставляемыми Android, вы не можете обновлять поток UIMain из другого потока.

Из-за вышеупомянутой причины вы получаете упомянутое сообщение во время запуска своего приложения.

Intereting Posts
Получение данных Firebase по приоритету (от самого низкого до самого высокого) не работает? Активность не привязана к Android.appActivity Manifest XML Почему @Override необходимо в Java или Android? Каков рекомендуемый способ создания Android-библиотек для использования в приложениях? Лучшая практика: AsyncTask во время изменения ориентации Как получить мой APP_KEY и SECRET_KEY для синхронизации Dropbox? Можем ли мы использовать почти все стандартные пакеты Java в приложении для Android? Андроид Разработка приложений для Android без Eclipse / ADT Установка textColor в TextView в макете / main.xml файл основного макета, не ссылающийся на файл colors.xml. (Он хочет #RRGGBB вместо @ color / text_color) Проникающая память адаптера изображения Интеграция ZbarScanner с приложением android Как сделать admob работать с версией Android версии <= 3.2? Android: SwitchCompat, проблемы с заполнением и цветом Загрузка изображения с сервера android на PHP