runOnUiThread funktioniert nicht

  • Antworten:5
Hauke Schrills
  • Forum-Beiträge: 67

08.05.2016, 22:00:38 via Website

Hallo Leute

Meiene App soll über Webservices die Daten einer Datenbank (SQLite) nach dem Start aktualisieren.
Für den AsyncTask und die Konvertrieung des JSon Strings benutze ich die Libraries von
https://github.com/kosalgeek/ Generic:Asynctasj_v2 und KGJSonConverter.
Das funktioniert auch einwandfrei. Nun kann das bei einer größeren Menge einige Zeit dauern.
Es kommt zwar die Meldung "Loading" mit dem rotierenden Kreis (welcher aber nach kurzer Zeit stehen bleibt),
ich würde aber lieber einen Countdown oder eine PRogressbar anzeigen.
das habe ich wie folgt versucht:

1)

runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        txt_Counter2.setText(DialigText);
                    }
                });

2)

private Runnable changeMessage = new Runnable() {
    @Override
    public void run() {
        txt_Counter2.setText(DialogText);
    }
};

und rufe dann
runOnUiThread(messagechange)
auf

Beides funktioniert jedoch nicht

Weis jemand Rat , wo der Haken liegt ?

Gruß Hauke

— geändert am 09.05.2016, 17:39:03

Antworten
Hauke Schrills
  • Forum-Beiträge: 67

09.05.2016, 15:24:38 via Website

Danke für die Antwort

Der Code lautet:

  PostResponseAsyncTask task_Mitglied = new PostResponseAsyncTask(MainActivity.this, new AsyncResponse() {
            @Override
            public void processFinish(String result) {
                // in JSON konvertieren
                ArrayList<Post_Mitglied> PostMitgliedList = new JsonConverter<Post_Mitglied>().toArrayList(result, Post_Mitglied.class);

                if(PostMitgliedList != null)
                    DB_MitzgliederAktualisieren(PostMitgliedList);
                else
                    Log.i("Fehler: ", "PostMitgliedList = null");
            }
        });
        JsonUrl=ServerUrl + holeStamp("Mitglieder") + "&service=mitglieder";  // URL des Webservices

        task_Mitglied.execute(JsonUrl);

Die Methode DB_MitgliederAktualisieren schreib die erhaltenen Daten in eine SQLite Tabelle:

 private void DB_MitzgliederAktualisieren(ArrayList<Post_Mitglied> postMitgliedList) {
        int j=0;  // Zähler auf Null

            try {
                for(Post_Mitglied value: postMitgliedList ) {  

                    String sqlStr = "INSERT OR REPLACE INTO mitglieder_3 VALUES('"      // insgeamt 43 Tabellen-Spalten)
                            + value.nr
                            + "','"
                              ........
                            + value.TIMESTAMP
                            + "','"
                            + value.Mobil + "');";

                    db_DBNAME.execSQL(sqlStr);

                    DialogText ="Mitglieder : "+ Integer.toString(j++);
           //         runOnUiThread(changeMessage);                                   // alternativ
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            txt_Counter2.setText("Testing");                              //<-- hier soll die Anzeige geändert werden.
                        }
                    });
                }

                String sqlStr = "INSERT OR REPLACE INTO time_stamps_3 (tabelle,time_stamp) VALUES ('Mitglieder','"
                        + t_date + "')";

                Log.i("Timestamp setzen:",sqlStr);
                db_DBNAME.execSQL(sqlStr);

            } catch (Exception e) {
                Log.i("Fehler bei Insert", e.toString());

            }
    }

PS :

Mit publisprogress habe ich noch nicht gearbeitet..

Antworten
Rafael K.
  • Forum-Beiträge: 2.359

10.05.2016, 10:54:43 via Website

Also ich kenne die AsyncTask LIB, die du da verwendest nicht, aber die Tatsache, dass Du die Verarbeitung in "processFinished" machst, klingt schonmal sehr falsch.
Im klassischen AsyncTask heißt die Methode für den langandauernden Hintergrund Task runInBackground() und so ähnlich wird sie wohl auch in deinem Framework lauten.
Mit anderen Worten: So wie Du das implementiert hast, wird deine Datenbank Arbeit wohl aktuell auf dem UI Thread gemacht.

Andererseits würde ich auch einfach den Standard-Async-Task nehmen und wie gesagt publishProgress.
"Hab ich noch nie gemacht" ist ja für Programmierer keine Ausrede ;)

Ein paar grundsätzliche Anregungen, um Deinen Code einfacher verständlich und wartbarer zu machen:
- Nutze Standard Java Code-Style. (Camel-Case für Variablennamen etc.)
- if IMMER mit geschweiften Klammern (siehe: https://nakedsecurity.sophos.com/2014/02/24/anatomy-of-a-goto-fail-apples-ssl-bug-explained-plus-an-unofficial-patch/)
- Nutze für Zugriff auf SQLite die zugehörigen Wrapper-Klassen, statt Plain-SQL. (SQL Injection)

Antworten
Hauke Schrills
  • Forum-Beiträge: 67

10.05.2016, 14:19:45 via Website

Danke für die Antwort.

Entschuldige erst einmal den wüsten Stil. Hab vieles hin- und her versucht und nicht gerade auf den Code-Style geachtet. (Mache ich auch meisten erst wenn es funktioniert).
Den Asynctask hatte ich nur für den Webservice gebraucht. Ich komme aber auch nicht an den Background Prozess heran. Ich hatte das in einer vorherigen App selber geschrieben, und werde wohl auf die Library verzichten. War halt ein Versuch.

PS mit 'habe ich noch nicht gemacht' meinte ich : 'kenne ich noch nicht' , aber man lernt nie aus.

danke und Gruß
Hauke

Antworten
Rafael K.
  • Forum-Beiträge: 2.359

10.05.2016, 16:27:42 via Website

Hauke Schrills

Den Asynctask hatte ich nur für den Webservice gebraucht. Ich komme aber auch nicht an den Background Prozess heran. Ich hatte das in einer vorherigen App selber geschrieben, und werde wohl auf die Library verzichten. War halt ein Versuch.

Du kommst nicht an den Background-Prozess heran?
In der Klasse des AsyncTask muss es doch eine Methode geben, die doInBackground heißt, oder du kannst diese Methode überschreiben.
Dort musst Du die Datenbankzugriffe machen. Das ist alles.

Vielleicht ist das hier auch als Grundlagen Lektüre hilfreich. Dort steht genau welche Methode des AsyncTask auf welchem Thread läuft.
http://developer.android.com/reference/android/os/AsyncTask.html

Antworten