私は初心者ですので、愚かな質問をすることを許してください
私は、ビュー階層を作成した元のスレッドだけがそのビューに触れることができるという意味を理解していません。
このエラーが発生した理由とこの問題の解決方法を教えてください。
ありがとうございました
これは私のクラスです
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)
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スレッドからのビューは変更できません。
この例外はtitle.clearComposingText()。が原因で発生しません。この行は役に立たない場合でも、この行を削除できます。この例外は、非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();
}
UIスレッドからのビューのみを変更できるため、スレッド内でtitle.clearComposingText();
を使用してテキストを変更することはできません。代わりにハンドラーを使用して、テキストを変更させてください。
UIスレッド以外のスレッドからtextViewを更新しないでください。これにはasynctaskを使用できます。参照できる this
他の人がすでに述べたように、バックグラウンドスレッドからUIを変更することはできません。
AsyncTask
を使用するか、 Activity.runOnUiThread()
メソッドを使用できます。