生成されたバックグラウンドサービスから元の活性のビューにアクセスする方法
-
18-09-2019 - |
質問
私は活性がAと呼ばれ、メニューアイテム0の選択に、それは新しいスレッドで実行可能なCを開始し、サービスBを、スポーン有します。私は、スレッドCにアクセスしたいアクティビティAでの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)
私はまた、意思を通じてビューを渡そうと考えたが、それがうまくいくか分かりません。私はこの仕事をするためには何が必要ですか?
解決
あなたはGUIスレッドからウィジェット、別名「ビュー階層を作成したスレッド」を更新する必要があります。これを行うための標準的な方法は、 Handler
のS経由での例ハンドラを使用する方法 ProgressDialog例を(で見つけることができます'第二のねじ山付き例ProgressDialog')を展開します。
他のヒント
私は、ListViewコントロールが別のスレッドからのWebサービスの応答に更新する必要があった同様の問題を抱えていた。
は、する &例には、ここであなたのために働く必要があります解決策は次のとおりです。
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のキーボードをスライドしたとします。あなたの活動は破壊され、再作成されます。あなたのサービスは、しかし、今はなき活動からウィジェット上に保持しています。せいぜい、アップデートは行われません。最悪の場合、アップデートは、クラッシュの原因となる、または古い活動がガベージコレクトすることはできませんので、あなたのサービスはまだその上に保持しているため、アプリケーションは、メモリリークが発生します。
サービス活動を通知持つことはあまりにも長い間、あなたがそれらの間でまともな分離を持っており、それが破壊されたときに活動がサービスから自分自身を切り離して、OKです。
他の方法は、処理のために os.android.AsyncTask を利用することである。