| 

.NET C# Java Javascript Exception

2
Hallo,

in meiner Android App führe ich eine SQLite Abfrage durch und berechne daraus eine neue Liste. Nun möchte ich den Benutzer über den Fortschritt informieren.

Leider wird der ProgressDialog nicht angezeigt, weil die Berechnung die gesamte Rechenzeit ein nimmt. Nun wollte ich diesen Prozess in einen neuen Thread auslagern.

Meine UI
[..]
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.hydranten);

dialog = new ProgressDialog(this);
dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
dialog.setMessage("Daten werden aufbereitet...");
dialog.setCancelable(false);
//dialog.show();

new Thread(new Runnable() {

public void run() {
openHandler = new HydrantenOpenHandler(this);
//openHandler.insert();

dbCursor = openHandler.query();
//System.out.println(dbCursor);

//Activity übernimmt Verwaltung des Cursors
startManagingCursor(dbCursor);
listAdapter = new HydrantenAdapter(this, dbCursor);
//dialog.dismiss();
}
}).start();

setListAdapter(listAdapter); //Sorgt für das Durchlaufen durch die Liste


}


Meine HydrantenOpenHandler:
[..]
HydrantenOpenHandler(Runnable runnable){
//System.out.println("Test");
super((Context) runnable, DATABASE_NAME, null, DATABASE_VERSION);
}
[..]


Nun stürzt mein App mit der Meldung bei LogCat:
07-23 11:46:19.081: E/AndroidRuntime(2286): FATAL EXCEPTION: Thread-370
07-23 11:46:19.081: E/AndroidRuntime(2286): java.lang.ClassCastException: com.teambroadcast.einsatz.HydrantenUI$1 cannot be cast to android.content.Context
07-23 11:46:19.081: E/AndroidRuntime(2286): at com.teambroadcast.einsatz.HydrantenOpenHandler.<init>(HydrantenOpenHandler.java:34)
07-23 11:46:19.081: E/AndroidRuntime(2286): at com.teambroadcast.einsatz.HydrantenUI$1.run(HydrantenUI.java:48)
07-23 11:46:19.081: E/AndroidRuntime(2286): at java.lang.Thread.run(Thread.java:856)


Liege ich hier überhaupt auf dem richtigen Weg? Und wie muss ich den OpenHandler starten, damit der mir nicht um die Ohren fliegt?

Stefan
News:
23.07.2012
DTAG 170 1 8
2 Antworten
1
Das "this" in

openHandler = new HydrantenOpenHandler(this);

ist die anonyme Implementierung von Runnable. Die Fehlermeldung sagt, dass im Konstruktor von HydrantenOpenHandler, und zwar in Zeile 34, dieses Objekt auf android.content.Context gecastet wird, was (verständlicherweise) schiefgeht. Deine anonyme Klasse leitet ja nicht von Context ab, sondern von Object.
23.07.2012
Matthias Hlawatsch 13,2k 4 9
Aber wie übergebe ich dem super() den korrekten Context?
DTAG 23.07.2012
Gegenfrage: zu welcher Klasse gehört onCreate(), hat diese Klasse Zugriff auf eine Context-Instanz oder ist sie sogar selbst von Context abgeleitet, und warum nimmst Du im Konstruktor von HydrantenOpenHandler explizit ein Runnable entgegen, wenn Du doch einen Context brauchst?
Matthias Hlawatsch 23.07.2012
1
So, ich habe den Context mal in eine Variable genommen: final Context context = this; um diese dann zu übergeben.

Eclipse hat mir die Änderung des Konstruktors "angeboten", ich habe es fälschlicherweise angenommen :-(
DTAG 23.07.2012
Ja ja, die IDE versucht *mit*zudenken, aber man sollte das nicht mit *alleine* denken verwechseln ;-)

Mit meinen höchst bescheidenen Android-Kenntnissen vermute ich mal, dass wir uns hier in einer von Activity und damit letztlich auch von Context abgeleiteten Klasse bewegen. Dann kannst Du den Konstruktor von HydrantenOpenHandler auch direkt mit "NameDeinerActivityKlasse.this" aufrufen und sparst Dir dann die Variable für den Context.
Matthias Hlawatsch 23.07.2012
1
Hi DTAG,

hast du dir mal die Klasse AsyncTask angesehen? Diese ermöglicht den simplen Umgang mit einen nebenläufigen Prozess(Thread) ohne das du dabei den Thread selbst implementieren musst.

Auf dein Beispiel könnte es so aussehen:
private class DBAbfrageTask extends AsyncTask<Void, Void, Boolean> {

private ProgressDialog dialog;

private Activity activity;

public DBAbfrageTask(Activity activity) {

this.activity = activity;
dialog = new ProgressDialog(activity);
}

protected void onPreExecute() {
dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
dialog.setMessage("Daten werden aufbereitet...");
dialog.setCancelable(false);
dialog.show();
}

@Override
protected Boolean doInBackground(Void... tmp){

//mach deine Berechnungen bzw Datenbank abfrage
return


}

@Override
protected void onPostExecute(Boolean result){

if (dialog.isShowing()) {
dialog.dismiss();
}

if(result){
//DB Abfrage war erfolgreich
}
else{
//Db Abfrage war nicht erfolgreich
}
}
}


Aufgerufen wird der ganze Spaß dann in deiner Activity per:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.hydranten);

new DBAbfrageTask(Kontakt.this).execute();
}


Mfg Flavius
24.07.2012
Flavius 186 3
Jo, habe ich. Ich wollte es aber auch mal selber machen ;-) Wenn das nicht geklappt hätte, hätte ich die wohl auch noch ausprobiert.
DTAG 24.07.2012

Stelle deine Android-Frage jetzt!