2009-07-21 1 views
29

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

Я пытался что делает 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) 

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

ответ

21

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

1

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

2

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

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

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

25

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

После анализа similar question & example, вот решение, которое должно работать для вас:

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(); 
} 
+2

примеры кода всегда так гораздо полезнее, чем описания. Спасибо :) – HXCaine

+0

Спасибо, эта проблема давно шла за мной! Спасибо! – Daniel

Смежные вопросы