web-dev-qa-db-ja.com

Android「ビュー階層を作成した元のスレッドのみがそのビューに触れることができます。」forループのエラー

Forループを0.5秒ごとに実行しようとしています。ループは呼び出されるたびにビュー内の何かを変更していますが、変更は別のクラス、つまりスピードメーターによって行われます。

Thread thread=new Thread(){
        @Override
        public void run() {
            float i;
            try {

                for ( i = 0; i <= 100; i++) {
                            Speedometer1.onSpeedChanged(Speedometer1.getCurrentSpeed(i) + 8);
                            Speedometer2.onSpeedChanged(Speedometer2.getCurrentSpeed(i) + 8);
                            Speedometer3.onSpeedChanged(Speedometer3.getCurrentSpeed(i) + 8);
                            Speedometer4.onSpeedChanged(Speedometer4.getCurrentSpeed(i) + 8);
                            Speedometer5.onSpeedChanged(Speedometer5.getCurrentSpeed(i) + 8);
                            Speedometer6.onSpeedChanged(Speedometer6.getCurrentSpeed(i) + 8);


                    sleep(500);
                }
            }
            catch (InterruptedException e)
            {e.printStackTrace();}
        }
    };thread.start();
16
Ariel

これは、どのスレッドもメインスレッドまたはUIスレッドでのみ変更できるためです。 onSpeedChanged()を使用してrunOnUiThread()を実行してみてください。このような:

    Thread thread=new Thread(){
    @Override
    public void run() {
        float i;
        try {

            for ( i = 0; i <= 100; i++) {
                runOnUiThread(new Runnable() {
                    public void run() {
                        Speedometer1.onSpeedChanged(Speedometer1.getCurrentSpeed(i) + 8);
                        Speedometer2.onSpeedChanged(Speedometer2.getCurrentSpeed(i) + 8);
                        Speedometer3.onSpeedChanged(Speedometer3.getCurrentSpeed(i) + 8);
                        Speedometer4.onSpeedChanged(Speedometer4.getCurrentSpeed(i) + 8);
                        Speedometer5.onSpeedChanged(Speedometer5.getCurrentSpeed(i) + 8);
                        Speedometer6.onSpeedChanged(Speedometer6.getCurrentSpeed(i) + 8)

                    }

                });


                sleep(500);
            }
        }
        catch (InterruptedException e)
        {e.printStackTrace();}
    }
};thread.start();
17
Miguel Benitez

runOnUIThreadのUIコンポーネントを更新する必要があります。サンプルコードは

runOnUiThread(new Runnable() {
     @Override
     public void run() {

       //stuff that updates ui

    }
});
9
Mujammil Ahamed

UIスレッドでUIを更新する必要があります。

そのためには、onCreate()メソッドでハンドラーを作成します。

private Handler mHandler;

@Override
public void onCreate() {
    mHandler = new Handler();
    // ...
}

次に、別のスレッドでハンドラーを呼び出して、メインスレッドで実行します。

mHandler.post(new Runnable() {
    @Override
    public void run() {
        // Update your UI
    }
});
7
xdevs23

メインスレッドの外部からViewオブジェクトを変更することはできません。 Speedometerクラスは変更を行っていますが、作成したセカンダリスレッドで実行されています。

Runnableを作成して、メインスレッドによって作成されたHandlerにdeejayで投稿するか、他の同様の手法を使用して同じことを達成できます。

0
Larry Schiefer