Ich habe ein Problem mit dem folgenden Fehler in Android:
CalledFromWrongThreadException ;: Nur der ursprüngliche Thread, der eine .__ erstellt hat. Die Ansichtshierarchie kann ihre Ansichten berühren
Es scheint zu geschehen, wenn ich versuche, eine Textansicht in meiner Aktivität zu aktualisieren, der Aufruf zur Aktualisierung der TextView von meiner Aktivität ausgeht, aber ich bekomme immer noch den obigen Fehler.
Ich habe es so:
onCreate () - legt die Schaltflächen und die Textansicht fest.
onStateChange () - Ein Listener für Benachrichtigungen über Statusänderungen, wenn eine Benachrichtigung angezeigt wird, wenn TextView geändert wird, um anderen Text anzuzeigen.
Wenn ich über einen neuen Text informiert werde, versuche ich, die Textansicht folgendermaßen zu ändern:
((TextView)findViewById(R.id.title)).setText("Some Text");
Ich bekomme aber den obigen Fehler.
Beim Googeln scheint es, als sollte ich einen Handler verwenden, um die TextView zu ändern, oder vielleicht AsyncTask verwenden?
Könnte jemand erklären, welche besser zu verwenden ist und warum?
BEARBEITEN: ADDED CODE SNIPPETS:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
setContentView(R.layout.my);
getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.my_title);
((TextView)findViewById(R.id.time)).setText("Hello Text");
findViewById(R.id.keyboardimage).setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Intent dialIntent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:"));
startActivity(dialIntent);
dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN,KeyEvent.FLAG_SOFT_KEYBOARD));
dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_BACK));
}
});
}
//CallBacks from running Service
private final ICallDialogActivity.Stub iCallDialogActivity = new ICallDialogActivity.Stub(){
@Override
public void onStateChanged(int callState)
throws RemoteException {
switch(callState){
case GlobalData.CALL_STATUS_IDLE:
break;
case GlobalData.CALL_STATUS_DISCONNECTING:
byeSetup();
break;
}
};
public void byeSetup(){
((TextView)findViewById(R.id.time)).setText("Bye Text");
findViewById(R.id.keyboardimage).setOnClickListener(new OnClickListener() {
public void onClick(View v) {
//Void the Button
}});
}
Sieht aus, als ob Sie im falschen Thread sind. Verwenden Sie einen Handler, um die GUI im rechten Thread zu aktualisieren. Siehe Umgang mit teuren Vorgängen im UI-Thread Beispiel von Android.com. Grundsätzlich würden Sie byeSetup
in eine Runnable
einschließen und mit einer Handler
-Instanz aufrufen.
Handler refresh = new Handler(Looper.getMainLooper());
refresh.post(new Runnable() {
public void run()
{
byeSetup();
}
});
Erweiterung der Antwort von willcodejavaforfood für Klarheit und Implementierung ...
Ich habe das zum Laufen gebracht und unten habe ich es gemacht. Ich führe mehrere Verarbeitungsthreads in einem Service aus, sodass andere Lösungen, die in Activity ausgeführt werden, nicht funktionieren, wie runOnUiThread (new Runnable () {} ...).
Stellen Sie dies an die Spitze Ihrer Serviceklasse, damit Sie in dieser Klasse überall verfügbar ist:
Handler handler;
Fügen Sie dies in Ihre Serviceklasse onCreate-Methode ein oder etwas, das im Service-Haupt-Thread geladen wird
handler= new Handler(Looper.getMainLooper());
Fügen Sie diesen Code in Ihren zusätzlichen Thread ein, um den Code "zurückzuschicken", damit er in der Benutzeroberfläche oder in der Service-Benutzeroberfläche ausgeführt werden kann.
handler.post(new Runnable() {
public void run() {
playNext(); //or whatever method you want to call thats currently not working
}
});
Für andere ersetzen Sie einfach byeSetup (); mit Ihren Code-Anweisungen oder Methoden. byeSetup () ist eine Beispielmethode. Ich hoffe, es wird etwas Zeit sparen.
Diese Methode ist nur für Activities und ist besser, wenn die Änderung am Haupt-Thread ( UiThread ) erfolgt. Verwenden Sie es in einem anderen Thread, um die Ansicht zu ändern.
runOnUiThread(new Runnable() {
@Override
public void run() {
// TODO your Code
et_Pass.setText("");
}
});
Ein weiterer Ansatz, bei dem Android.os.Message
verwendet wird
Haben Sie Android.os.Handler
als Feld in Ihrer Aktivität definiert:
private final Handler myTextHandler = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(Message stringMessage) {
textView.append((String) stringMessage.obj);
return true;
}
});
Dann füttere es aus deinem anderen Thread wie folgt:
Message stringMessage = Message.obtain(myTextHandler);
stringMessage.obj = "Hello!";
stringMessage.sendToTarget();
Sie können die eingebaute Post-Methode von view verwenden, um den Inhalt in einem anderen Thread zu aktualisieren, z.
address_box.post { address_box.text="my text"}