Intereting Posts
Как управлять жизненным циклом в классе, создаваемом в ViewGroup? ProGuard не может найти ссылки на библиотеки Импортируйте CSV-файл в Sqlite на Android Как самостоятельно удалить приложение? Незарегистрированная ошибка токена после отправки одного уведомления Объединение ListActivity и ActionBarActivity Разница между <include> и <ViewStub> в android Требование упоминать версию сервисов Google Play в манифесте приложения Как получить выбранные элементы списка из списка с помощью checkbox и пользовательского адаптера? Чтение всех сегодняшних событий с помощью CalendarContract – Android 4.0+ Поиск предложений с сетевого ресурса в поле быстрого поиска Неудовлетворенная ошибка связи – OpenCV для Android Калабаш-андроид: подключитесь к запущенному приложению Лучшая практика для определения событий кнопки в android Android: автозаполнение Google Места. Как я могу использовать его для заполнения RecyclerView, а не в раскрывающемся меню?

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

У меня есть действие под названием A, и при выборе пункта меню 0 он запускает службу B, которая запускает исполняемый C в новом потоке. У меня есть TextView в действии A, к которому я хочу получить доступ в потоке C.

Я попытался сделать TextView общедоступным статическим полем, но это порождает следующую ошибку:

07-21 07:26:25.723: ERROR/AndroidRuntime(1975): android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views. 07-21 07:26:25.723: ERROR/AndroidRuntime(1975): at android.view.ViewRoot.checkThread(ViewRoot.java:2440) 07-21 07:26:25.723: ERROR/AndroidRuntime(1975): at android.view.ViewRoot.invalidateChild(ViewRoot.java:522) 07-21 07:26:25.723: ERROR/AndroidRuntime(1975): at android.view.ViewRoot.invalidateChildInParent(ViewRoot.java:540) 07-21 07:26:25.723: ERROR/AndroidRuntime(1975): at android.view.ViewGroup.invalidateChild(ViewGroup.java:2332) 07-21 07:26:25.723: ERROR/AndroidRuntime(1975): at android.view.View.invalidate(View.java:4437) 07-21 07:26:25.723: ERROR/AndroidRuntime(1975): at android.widget.TextView.updateAfterEdit(TextView.java:4593) 07-21 07:26:25.723: ERROR/AndroidRuntime(1975): at android.widget.TextView.handleTextChanged(TextView.java:5932) 07-21 07:26:25.723: ERROR/AndroidRuntime(1975): at android.widget.TextView$ChangeWatcher.onTextChanged(TextView.java:6081) 07-21 07:26:25.723: ERROR/AndroidRuntime(1975): at android.text.SpannableStringBuilder.sendTextChange(SpannableStringBuilder.java:889) 07-21 07:26:25.723: ERROR/AndroidRuntime(1975): at android.text.SpannableStringBuilder.change(SpannableStringBuilder.java:352) 07-21 07:26:25.723: ERROR/AndroidRuntime(1975): at android.text.SpannableStringBuilder.change(SpannableStringBuilder.java:269) 07-21 07:26:25.723: ERROR/AndroidRuntime(1975): at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:432) 07-21 07:26:25.723: ERROR/AndroidRuntime(1975): at android.text.SpannableStringBuilder.append(SpannableStringBuilder.java:259) 07-21 07:26:25.723: ERROR/AndroidRuntime(1975): at android.text.SpannableStringBuilder.append(SpannableStringBuilder.java:28) 07-21 07:26:25.723: ERROR/AndroidRuntime(1975): at android.widget.TextView.append(TextView.java:2191) 07-21 07:26:25.723: ERROR/AndroidRuntime(1975): at android.widget.TextView.append(TextView.java:2178) 07-21 07:26:25.723: ERROR/AndroidRuntime(1975): at com.android.peekaboo.DoScan$scanBody.run(DoScan.java:36) 07-21 07:26:25.723: ERROR/AndroidRuntime(1975): at java.lang.Thread.run(Thread.java:1058) 

Я также подумал о попытке передать представление через намерение, но не знаю, как это будет работать. Что мне нужно для выполнения этой работы?

Solutions Collecting From Web of "Как получить доступ к представлениям оригинальной активности из созданной фоновой службы"

Вам нужно обновить виджеты из потока графического интерфейса пользователя, а также «поток, создавший иерархию представлений». Стандартный способ сделать это через Handler s, и пример использования обработчиков можно найти в примере ProgressDialog (развернуть «Пример ProgressDialog со вторым потоком»).

У меня была аналогичная проблема, когда ListView должен был обновляться в ответ на веб-службу, исходящий из отдельного потока.

После анализа аналогичного вопроса, например , вот решение, которое должно работать на вас:

 public class A extends Activity implements Callback { callserviceB () { } // where your service B being called; @Override public void returnServiceResponse() { workOnResponse(); handler.sendEmptyMessage(0); } private Handler handler = new Handler() { public void handleMessage(Message msg) { //update your view from here only. } } } public class B implements Runnable { Callback callback; public void run() { //your business logic. callback.returnServiceResponse(); } } public interface Callback { public void returnServiceResponse(); } 

Вы действительно не хотите напрямую манипулировать виджетами из службы.

Например, предположим, что пользователь выталкивает клавиатуру своего G1. Ваша деятельность разрушена и воссоздана. Однако ваш сервис держится на виджетах от ныне несуществующей активности. В лучшем случае обновления не будут происходить. В худшем случае обновления приведут к сбою, или ваше приложение будет утечка памяти, потому что старая активность не может быть собрана с мусором, потому что ваша служба все еще удерживает ее.

Службы уведомляют о деятельности в порядке, если у вас есть достойная изоляция между ними, и деятельность отрывается от службы при ее уничтожении.

Другой способ – использовать os.android.AsyncTask для обработки.