Je ne suis qu'un débutant, alors pardonnez-moi de vous avoir posé une question stupide
Je ne comprends pas la signification de Seul le fil d'origine qui a créé une hiérarchie de vues peut toucher ses vues.
S'il vous plaît quelqu'un peut-il m'apprendre pourquoi cette erreur se produit et comment résoudre ce problème.
Merci
C'est ma classe
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);
}
}
Et voici mon 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)
Modifiez votre startingUp()
en ceci.
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();
}
Vous ne pouvez pas modifier les vues à partir d'un thread non-UI.
Cette exception ne vient pas à cause de title.clearComposingText (). même cette ligne n'est pas utile, nous pouvons supprimer cette ligne. Cette exception arrive dans la fonction title () car un thread non UI essaie de modifier la vue. nous devons donc appeler cette fonction dans un ( Thread d'interface utilisateur ou gestionnaire.
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();
}
Vous ne pouvez pas modifier le texte avec title.clearComposingText();
à l'intérieur du thread car vous ne pouvez modifier les vues qu'à partir du thread d'interface utilisateur. Utilisez plutôt un gestionnaire et laissez-le modifier le texte.
Vous ne devez pas mettre à jour textView à partir d'un thread autre que le thread d'interface utilisateur.Vous pouvez utiliser une tâche asynctrogue pour cela.Pouvez vous référer ceci
Comme d'autres personnes l'ont déjà dit, vous ne pouvez pas modifier l'interface utilisateur à partir d'un thread d'arrière-plan.
Vous pouvez soit utiliser AsyncTask
, soit utiliser la méthode Activity.runOnUiThread()