3

エラーの取得: android.view.ViewRootImpl$CalledFromWrongThreadException: ビュー階層を作成した元のスレッドのみがそのビューにアクセスできます。
理由がまったくわかりません。

  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Button generate = (Button) findViewById(R.id.gen);
    final TextView dice1 = (TextView) findViewById(R.id.dice1);
    final TextView dice2 = (TextView) findViewById(R.id.dice2);
    final TextView dice3 = (TextView) findViewById(R.id.dice3);


    generate.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {           
            dice1.setText(" ");
            dice2.setText(" ");
            dice3.setText(" ");         
            Thread thread = new Thread()
            {
                @Override
                public void run() {
                    try {
                        while(true) {
                            sleep(2000);
                            setText("lol", "lol", "lol");
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            };
            thread.start();             
        }

    });
}
public void setText(String d1, String d2, String d3){
    dice1.setText(d1);
    dice2.setText(d2);
    dice3.setText(d3);  
}

助けてくれてありがとう。

4

3 に答える 3

2

文字通り、間違ったスレッドからビューにフィールドを設定しようとしています。OnClickListener は新しいスレッドを作成しますが、ビューとその階層を作成したスレッドのみがそれらのビューを変更できます。

http://developer.android.com/reference/java/util/concurrent/ScheduledThreadPoolExecutor.htmlを使用するようにリファクタリングできます。

または、setter コードを runOnUiThread ブロック内にラップすることもできます。Android: RunOnUiThread vs AsyncTaskというサイトに例があり、これが良い考えではない理由についての注意事項があります。

于 2013-06-18T19:02:21.057 に答える
1

スレッドごとに setText を設定しています。UI コンポーネントを操作するメソッドを呼び出すメソッドを runOnUiThread ブロック内に配置します。

于 2013-06-18T18:59:26.153 に答える