29

A というアクティビティがあり、メニュー項目 0 を選択するとサービス B が生成され、新しいスレッドで実行可能な C が開始されます。スレッド C でアクセスしたいアクティビティ A に TextView があります。

TextView を public static フィールドにしようとしましたが、次のエラーが発生します。

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)

ビューをインテントで渡そうとすることも検討しましたが、それがどのように機能するかわかりません。これを機能させるには何が必要ですか?

4

4 に答える 4

25

別のスレッドからのWebサービス応答で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();
}
于 2010-09-03T05:00:35.987 に答える
21

GUIスレッド、別名「ビュー階層を作成したスレッド」からウィジェットを更新する必要があります。これを行う標準的な方法はHandlers を使用することであり、ハンドラーの使用方法の例は、ProgressDialog の例(「2 番目のスレッドを使用した ProgressDialog の例」を展開) にあります。

于 2009-07-21T09:56:46.457 に答える
2

あなたは本当にサービスからウィジェットを直接操作したくありません。

たとえば、ユーザーがG1のキーボードをスライドさせたとします。あなたの活動は破壊され、再作成されます。ただし、サービスは、現在は機能していないアクティビティからのウィジェットを保持しています。せいぜい、更新は発生しません。最悪の場合、更新によってクラッシュが発生したり、サービスがまだ保持しているために古いアクティビティをガベージコレクションできないために、アプリケーションがメモリリークを起こしたりします。

サービスにアクティビティを通知させることは、それらの間に適切な分離があり、アクティビティが破棄されたときにサービスから切り離される限り、問題ありません。

于 2009-07-21T21:39:34.780 に答える