23

私はまだ初心者なので、ばかげた質問をすることを許してください


ビュー階層を作成した元のスレッドだけがそのビューに触れることができるという意味がわかりません。

誰かがこのエラーが発生している理由とこの問題を解決する方法を教えてもらえますか?

ありがとうございました

これは私のクラスです

public class MainActivity extends Activity {
    TextView title;
    Random   random  = new Random();
    int      counter = 1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.startup);
        startingUp();
    }

    private void startingUp() {
        Thread timer = new Thread() { //new thread         
            public void run() {
                Boolean b = true;
                try {
                    do {
                        counter++;
                        title();
                        sleep(1000);
                        title.clearComposingText();

                    }
                    while (b == true);
                } catch (IntruptedException e) {
                    e.printStackTrace();
                }
                finally {
                }
            };
        };
        timer.start();
    }

    public void title() {
        title = (TextView) findViewById(R.id.tvTitle);
        switch (random.nextInt(2)) {
            case 0:
                title.setGravity(Gravity.RIGHT);
                break;
            case 1:
                title.setGravity(Gravity.CENTER);
                break;
            case 2:
                title.setGravity(Gravity.LEFT);
                break;
        }
        title.setTextColor(Color.rgb(random.nextInt(250), random.nextInt(250), random.nextInt(250)));
        title.setTextSize(random.nextInt(55) + 10);
    }
}

そしてこれは私のLogCatです

02-20 10:53:19.293: I/Adreno200-EGLSUB(5816): <ConfigWindowMatch:2078>: Format RGBA_8888.
02-20 10:53:19.303: D/memalloc(5816): /dev/pmem: Mapped buffer base:0x5c914000 size:14135296 offset:10366976 fd:64
02-20 10:53:19.303: E/(5816): Can't open file for reading
02-20 10:53:19.303: E/(5816): Can't open file for reading
02-20 10:53:19.303: D/OpenGLRenderer(5816): Enabling debug mode 0
02-20 10:53:19.373: D/memalloc(5816): /dev/pmem: Mapped buffer base:0x5db58000 size:3768320 offset:0 fd:67
02-20 10:53:20.143: W/dalvikvm(5816): threadid=11: thread exiting with uncaught exception (group=0x40abc210)
02-20 10:53:20.143: E/AndroidRuntime(5816): FATAL EXCEPTION: Thread-3102
02-20 10:53:20.143: E/AndroidRuntime(5816): android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
02-20 10:53:20.143: E/AndroidRuntime(5816):     at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:4039)
02-20 10:53:20.143: E/AndroidRuntime(5816):     at android.view.ViewRootImpl.invalidateChild(ViewRootImpl.java:722)
02-20 10:53:20.143: E/AndroidRuntime(5816):     at android.view.ViewRootImpl.invalidateChildInParent(ViewRootImpl.java:771)
02-20 10:53:20.143: E/AndroidRuntime(5816):     at android.view.ViewGroup.invalidateChild(ViewGroup.java:4112)
02-20 10:53:20.143: E/AndroidRuntime(5816):     at android.view.View.invalidate(View.java:8639)
02-20 10:53:20.143: E/AndroidRuntime(5816):     at android.view.View.invalidate(View.java:8590)
02-20 10:53:20.143: E/AndroidRuntime(5816):     at android.widget.TextView.setGravity(TextView.java:2538)
02-20 10:53:20.143: E/AndroidRuntime(5816):     at com.example.saikoro.MainActivity.title(MainActivity.java:58)
02-20 10:53:20.143: E/AndroidRuntime(5816):     at com.example.saikoro.MainActivity$1.run(MainActivity.java:36)
4

5 に答える 5

31

これに変更startingUp()します。

 private void startingUp() {
    Thread timer = new Thread() { //new thread         
        public void run() {
            Boolean b = true;
            try {
                do {
                    counter++;
                    title();
                    sleep(1000);

                    runOnUiThread(new Runnable() {  
                    @Override
                    public void run() {
                        // TODO Auto-generated method stub

                        title.clearComposingText();
                    }
                });


                }
                while (b == true);
            } catch (IntruptedException e) {
                e.printStackTrace();
            }
            finally {
            }
        };
    };
    timer.start();
}

UI以外のスレッドからビューを変更することはできません。

于 2013-02-20T11:04:22.080 に答える
11

title.clearComposedText()が原因で、この例外は発生しません。 この行でも役に立ちません。この行を削除できます。非UIスレッドがビューを変更しようとしているため、この例外はtitle()関数に発生します。したがって、 UIスレッドまたはハンドラー でこの関数を呼び出す必要があります。

private void startingUp() {
        Thread timer = new Thread() { //new thread         
            public void run() {
                boolean b = true;
                try {
                    do {
                        counter++;

                        sleep(1000);
                        runOnUiThread(new Runnable() {

                            @Override
                            public void run() {
                                  title();
                                //title.clearComposingText();//not useful

                            }
                        });


                    }
                    while (b == true);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                finally {
                }
            };
        };
        timer.start();
    }
于 2013-07-10T10:26:01.183 に答える
2

title.clearComposingText();UIスレッドからのビューしか変更できないため、スレッド内でテキストを変更することはできません。代わりにハンドラーを使用して、テキストを変更させてください。

于 2013-02-20T10:59:59.657 に答える
2

UIスレッド以外のスレッドからtextViewを更新しないでください。これにはasynctaskを使用できます。これを参照できます。

于 2013-02-20T11:01:35.043 に答える
2

他の人がすでに述べたように、バックグラウンドスレッドからUIを変更することはできません。

AsyncTaskを使用するか、Activity.runOnUiThread()メソッドを使用できます

于 2013-02-20T11:05:21.660 に答える