52

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
                }});
}
4

6 に答える 6

82

あなたが間違ったスレッドにいるように見えます。ハンドラーを使用して、適切なスレッドで GUI を更新してみてください。android.comの UI スレッドの例で、高価な操作の処理を参照してください。基本的に、 でラップbyeSetupし、インスタンスRunnableで呼び出します。Handler

Handler refresh = new Handler(Looper.getMainLooper());
refresh.post(new Runnable() {
    public void run()
    {
        byeSetup();
    }
});
于 2010-07-19T12:36:03.227 に答える
3

明確化と実装のために、willcodejavaforfoodの回答を拡張しています...

私はこれを機能させました。以下は私がそれを行った方法です。サービスで複数の処理スレッドを実行しているため、runOnUiThread(new Runnable() {}... など、アクティビティで実行される他のソリューションが機能しません。

これをサービス クラスの先頭に配置して、このクラスのどこからでもアクセスできるようにします。

Handler handler;

これをサービスクラスの onCreate メソッドまたはサービスのメインスレッドにロードする何かに入れます

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
    }
});
于 2015-01-07T03:17:29.487 に答える
2

それ以外の場合は、byeSetup(); を置き換えるだけです。コードステートメントまたはメソッドで。byeSetup() はサンプルメソッドです。時間を節約できることを願っています。

于 2012-05-25T21:36:38.010 に答える