如何从产生的后台服务访问原始活动的视图

问题描述:

我有一个名为A的活动,并且在菜单项0的选择上,它产生了服务B,它在新线程中启动可运行的C.我有活性的一个TextView,我想在线程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) 

我也有考虑试图通过意图传递视图,但不知道如何工作。我需要做什么来完成这项工作?

您必须从GUI线程更新小部件,也就是'创建视图层次结构的线程'。执行此操作的标准方法是通过Handler s,并且可以在ProgressDialog Example(展开'使用第二个线程'示例ProgressDialog')中找到如何使用处理程序的示例。

另一种方式是利用os.android.AsyncTask进行处理。

你真的不想直接操作服务中的小部件。

例如,假设用户滑出她的G1的键盘。你的活动被破坏并重新创建。但是,您的服务正在遏制现已不存在的活动的小部件。充其量,更新不会发生。最坏的情况是,更新会导致崩溃,或者你的应用程序会泄漏内存,因为旧的活动不能被垃圾回收,因为你的服务仍然支持它。

让服务通知活动是可以的,只要你有良好的隔离,活动就会在服务被销毁时从服务中分离出来。

我有一个类似的问题,其中ListView需要更新的Web服务响应来自一个单独的线程。

分析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 2011-01-04 00:01:01