Update UI in der Haupt-Aktivität durch hf in einem thread (Android)
Ich versuche, mehrere connection in einer Klasse und zu aktualisieren, die mehrere progressbar in der Haupt-Bildschirm.
Aber ich hab den folgenden Fehler beim Versuch zu verwenden-thread in android :
Code:
05-06 13:13:11.092: FEHLER/ConnectionManager(22854): ERROR:Can ' T create handler inside thread, der nicht genannt Looper.prepare()
Hier ist ein kleiner Teil von meinem code in der main-Activity
public class Act_Main extends ListActivity
{
private ConnectionManager cm;
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
//Set up the window layout
requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
setContentView(R.layout.main);
getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.custom_title);
}
public void startConnection()
{
//open DB connection
db = new DBAdapter(getApplicationContext());
db.open();
cm = new ConnectionManager(handler, db);
showDialog(DIALOG_PROGRESS_LOGIN);
}
@Override
public void onStart()
{
super.onStart();
startConnection();
}
protected Dialog onCreateDialog(int id)
{
switch (id)
{
case DIALOG_PROGRESS_LOGIN:
progressDialog = new ProgressDialog(Act_Main.this);
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDialog.setMessage("Connecting.\nPlease wait...");
progressThreadLogin = new ProgressThreadLogin();
progressThreadLogin.start();
return progressDialog;
case DIALOG_PROGRESS_NETWORK:
[b]progressDialog = new ProgressDialog(Act_Main.this);[/b]
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDialog.setMessage("Loading entire network.\nPlease wait...");
progressThreadNetwork = new ProgressThreadNetwork();
progressThreadNetwork.start();
return progressDialog;
default:
return null;
}
}
//Define the Handler that receives messages from the thread and update the progress
final Handler handler = new Handler()
{
public void handleMessage(Message msg)
{
int total = msg.getData().getInt("total");
int step = msg.getData().getInt("step");
Log.d(TAG, "handleMessage:PROCESSBAR:"+total);
progressDialog.setProgress(total);
if (total >= 100)
{
switch (step)
{
case UPDATE_NETWORK:
dismissDialog(DIALOG_PROGRESS_LOGIN);
showDialog(DIALOG_PROGRESS_NETWORK);
cm.getNetwork();
break;
....
default:
break;
}
}
}
};
private class ProgressThreadLogin extends Thread
{
ProgressThreadLogin() { }
public void run() { cm.login(); }
}
private class ProgressThreadNetwork extends Thread
{
ProgressThreadNetwork() { }
public void run() { cm.getNetwork(); }
}
}
Und meine connectionManager-Klasse:
public class ConnectionManager
{
public ConnectionManager(Handler handler, DBAdapter db)
{
this.handler = handler;
this.db = db;
}
public void updateProgressBar(int step, int value)
{
if (value == 0)
total = total+1;
else
total = value ;
Message msg = handler.obtainMessage();
Bundle b = new Bundle();
b.putInt("total", total);
b.putInt("step", step);
msg.setData(b);
handler.handleMessage(msg);
}
public void login()
{
//DO MY LOGIN TASK
updateProgressBar(Act_Main.UPDATE_NETWORK, 100);
}
}
Den crash-Fehler tritt in der ersten Zeile der "Fall DIALOG_PROGRESS_NETWORK:". Meine erste progressbar ist ausgeblendet, aber die zweite wird nicht angezeigt.
Ich denke, dass ich getan habe, etwas falsch mit den threads und Handler, aber ich dont' wissen, warum.
War ich zuerst mit hf.sendMessage an Stelle von hf.handleMessage aber wenn ich hatte mehrere Pläne in meinem connectionManager, die progressbar aktualisiert wurde erst am Ende aller Aufgaben.
Vielen Dank im Voraus für Eure Hilfe
InformationsquelleAutor Hrk | 2010-05-09
Du musst angemeldet sein, um einen Kommentar abzugeben.
Machen
Handler handler
nicht-Finale und init es inonCreate()
.new Handler()
in Ihrer Klasse definition (Das ist auch nicht die richtige java; Sie können nur initialisieren static - Objekt in der definition der Klasse). Plus gibt es keinen Grund für es zu sein endgültig. Ein handler ist gebunden an den thread, in dem es erstellt wurde, und dieser thread muss eine message-queue / looper. Legen Sie Sie inonCreate()
ist die richtige Art und Weise zu binden, den handler in der main-UI-thread.Sie sind falsch.. Wir können auf jeden Fall rufen Sie die neue Methode, wenn wir wollen ( aber das ist sagte, um eine schlechte Praxis) als Nächstes sagte: "Sie können nur initialisieren einer statischen Objekts in der definition der Klasse" wieder liegen Sie falsch, können wir initialisieren alle Variablen, die wir wie in der definition der Klasse ...
InformationsquelleAutor yanchenko
Dass der Hf-Finale und die Deklaration in der Klassendefinition ist das völlig in Ordnung.
Außerdem in deinem letzten code-snippet, wenn Sie die initialize-Ereignishandler in onCreate, Sie sind tatsächlich "Schatten" der Hundeführer erklärt, in Ihrer Klasse, also nicht initialisieren. Ich bin ziemlich überrascht, Sie nicht hatte keine NullPointerException.
Aber in ConnectionManager::updateProgressBar Sie wirklich brauchen, um call sendMessage (), da durch Aufruf der handleMessage() direkt, der handler wird aufgerufen, aus dem thread von ConnectionManager::updateProgressBar (was wahrscheinlich nicht der UI-thread).
Ich bin mir nicht sicher, was Sie verursacht das problem, dass der Fortschrittsbalken aktualisiert, nur einmal, aber es ist sicherlich ein Logik-Fehler irgendwo.
Versuchen, sich bei verschiedenen Schritten der app -ie. vor dem versenden der Nachricht und beim Umgang mit es-.
InformationsquelleAutor Gautier Hayoun
Hrk, die Abschattung Teil ist, wenn Sie deklarieren eine lokale variable innerhalb der Methode, die denselben Namen hat wie das Feld, in:
Um das Feld zu nutzen, weglassen-Typ:
In Bezug auf Ausnahme, nur instanziieren
ProgressDialog
Objekte im main-thread (z.B. in onCreate () - Methode) und rufen Sie die show () - Methoden später.InformationsquelleAutor Tomislav