Androidで次のエラーが発生します。
CalledFromWrongThreadException ;:ビュー階層を作成した元のスレッドのみがそのビューに触れることができます
アクティビティでTextviewを更新しようとすると発生するようです。TextViewを更新するための呼び出しはアクティビティ内からですが、上記のエラーが発生します。
私はこれを次のように持っています:
onCreate()-ボタンとテキストビューを設定します。
onStateChange()-状態の変化に関する通知のリスナー。これは、TextViewを変更して異なるテキストを言う場合に通知を取得します。
新しいテキストの通知を受け取ったら、TextViewを次のように変更しようとします。
((TextView)findViewById(R.id.title)).setText("Some Text");
しかし、上記のエラーが発生します。
グーグルから、ハンドラを使用してTextViewを変更するか、AsyncTaskを使用する必要がありますか?
誰が使用する方が良いか、そしてその理由を説明できますか?
編集:コードスニペットの追加:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
setContentView(R.layout.my);
getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.my_title);
((TextView)findViewById(R.id.time)).setText("Hello Text");
findViewById(R.id.keyboardimage).setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Intent dialIntent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:"));
startActivity(dialIntent);
dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN,KeyEvent.FLAG_SOFT_KEYBOARD));
dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_BACK));
}
});
}
//CallBacks from running Service
private final ICallDialogActivity.Stub iCallDialogActivity = new ICallDialogActivity.Stub(){
@Override
public void onStateChanged(int callState)
throws RemoteException {
switch(callState){
case GlobalData.CALL_STATUS_IDLE:
break;
case GlobalData.CALL_STATUS_DISCONNECTING:
byeSetup();
break;
}
};
public void byeSetup(){
((TextView)findViewById(R.id.time)).setText("Bye Text");
findViewById(R.id.keyboardimage).setOnClickListener(new OnClickListener() {
public void onClick(View v) {
//Void the Button
}});
}
間違ったスレッドにいるように見えます。ハンドラーを使用して、正しいスレッドでGUIを更新してみてください。 Android.comの UIスレッドでの高価な操作の処理 の例を参照してください。基本的に、byeSetup
でRunnable
をラップし、Handler
インスタンスで呼び出します。
Handler refresh = new Handler(Looper.getMainLooper());
refresh.post(new Runnable() {
public void run()
{
byeSetup();
}
});
Willcodejavaforfoodの答えを明確にして実装するために拡大しています...
これが機能するようになりました。以下にその方法を示します。サービスで複数の処理スレッドを実行しているため、runOnUiThread(new Runnable(){} ...など、Activityで実行される他のソリューションは機能しません。
これをサービスクラスの先頭に配置して、このクラスのどこからでもアクセスできるようにします。
Handler handler;
これをサービスクラスのonCreateメソッドまたはServiceメインスレッドでロードするものに入れます
handler= new Handler(Looper.getMainLooper());
これを追加のスレッド内に配置して、コードを「ポストバック」し、UIまたはサービスUI(と呼ばれるもの)で実行します。
handler.post(new Runnable() {
public void run() {
playNext(); //or whatever method you want to call thats currently not working
}
});
変更がメインスレッドに関係する場合(iThread)。ビューを変更するには、別のスレッド内で使用します。
runOnUiThread(new Runnable() {
@Override
public void run() {
// TODO your Code
et_Pass.setText("");
}
});
その他の場合は、byeSetup()を置き換えるだけです。コードステートメントまたはメソッドを使用します。 byeSetup()はサンプルメソッドです。時間の節約になることを願っています。
別のアプローチ、今度はAndroid.os.Message
持ってる Android.os.Handler
アクティビティ内のフィールドとして定義:
private final Handler myTextHandler = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(Message stringMessage) {
textView.append((String) stringMessage.obj);
return true;
}
});
次に、他のスレッドから次のようにフィードします。
Message stringMessage = Message.obtain(myTextHandler);
stringMessage.obj = "Hello!";
stringMessage.sendToTarget();
ビューの組み込みのpostメソッドを使用して、kotlinで編集テキストを使用しているように、他のスレッドのコンテンツを更新できます。
address_box.post { address_box.text="my text"}