Korrektes vorgehen für Internet Überprüfung und Datenbankversion abfrage

  • Antworten:9
Volkan Aydin
  • Forum-Beiträge: 187

10.05.2014, 22:43:31 via Website

Es ist wiedermal soweit... Nach einer Woche problemlosem gebastel, stehe ich wieder mal an einem Problem an, das ich überhaupt nicht verstehe was da jetzt verlangt wird. die fehlermeldung ist :

Error in http connectionandroid.os.NetworkOnMainThreadException

Soweit so gut, hier wird anscheinend verlangt das ich das ganze in einem anderem Thread starten muss? Doch weshalb ist das so? Ich möchte Folgendes.

Nach dem Login wird eine neue activity samt xml gestartet.

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);
        setContentView(R.layout.gr_ubersicht);
        checkDbVersionOnAndroid();
    }

Wie man hier sieht, versuche ich nach dem setContentView diese funktion aufzurufen, darin wird überprüft ob eine sqlite db erstellt wurde im app. das hat glaube ich funktioniert :) Darin wird eine Versionsnr gespeichert.

Nun brauche ich eine Internetverbindung zu einer php Seite die mir die aktuelle Version db-nr liefert.... nun, so wie ich das verstanden habe muss ich nun dieses runnable verwenden, um diese zu starten?.

runOnUiThread(new Runnable(){
                 public void run(){
                    checkMysqlVersionNr(); 
                 }
             }); 

und zwar mit dem runOnUIThread, da ich ja nicht will, das es eine neue activity lädt?....

sieht man hier schon was ich falsch mache? oder braucht ihr noch mehr Code????? wieso braucht es dazu überhaubt einen neuen thread? ist das wegen den progress.dialogen?

hier mal der ganze fehlerprotokoll.......

05-10 20:34:04.607: E/log_tag(5939): Error in http connectionandroid.os.NetworkOnMainThreadException
05-10 20:34:04.627: E/log_tag(5939): Error in readjava.lang.NullPointerException: lock == null
05-10 20:34:04.747: E/log_tag(5939): SQL DB_fehlerandroid.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 0
05-10 20:34:04.797: I/Choreographer(5939): Skipped 60 frames!  The application may be doing too much work on its main thread.
05-10 20:34:05.357: W/EGL_emulation(5939): eglSurfaceAttrib not implemented
05-10 20:34:05.457: I/Choreographer(5939): Skipped 31 frames!  The application may be doing too much work on its main thread.

Danke schon mal!

— geändert am 10.05.2014, 22:46:04

Antworten
impjor
  • Forum-Beiträge: 1.793

11.05.2014, 00:08:40 via App

Du würfelst da einiges durcheinander....

Hast du mal nach "android NetworkOnMainThreadException" gegoogelt?

Sonst steht auch alles notwendige z.B. hier: https://www.nextpit.de/forum/568854/tutorial-download-einer-webseite

Es wäre extrem vorteilhaft, wenn du dich mit Threading auskennen würdest.
Mit runOnUiThread machst du übrigens genau das Gegenteil vom Gewünschten, du willst einen neuen Thread, nicht den UI-Thread.

— geändert am 11.05.2014, 00:09:26

Liebe Grüße impjor.

Für ein gutes Miteinander: Unsere Regeln
Apps für jeden Einsatzzweck
Stellt eure App vor!

Antworten
Sven R.
  • Forum-Beiträge: 1.904

11.05.2014, 11:18:25 via App

Du musst deine ganzen Netzwerkgeschichten in einen neuen Thread auslagern:

Thread checkInternetDb = new Thread( new Runnable(

bla()

));

checkInternetDb.start();

Edit: Mit runOnUiThread() kannst du in deinem Netzwerk Thread auf Views, ... zugreifen.

— geändert am 11.05.2014, 11:21:24

Wenn dir mein Beitrag gefällt, kannst dich einfach mit dem 👍 "Danke"-Button auf der Website dieses Forums bedanken. 😀

Why Java? - Because I can't C#

Antworten
Volkan Aydin
  • Forum-Beiträge: 187

11.05.2014, 13:50:51 via Website

Irgendwie bin ich da noch nicht ganz so Sattelfest..... also hier mal der Code in schöner reihenfolge, mit Kommentaren dazwischen...

public class rechner extends Activity {

//Variablen
 StringBuffer buffer;
    List<NameValuePair> nameValuePairs;
    ProgressDialog dialog = null;

final static String MY_DB_NAME = "awad";
final static String MDT_version = "version";
final static String tag="ensacom";
final static String version_nr = "version_nr";
    SQLiteDatabase myDB = null;


protected void onCreate(Bundle savedInstanceState) {



    super.onCreate(savedInstanceState);
    setContentView(R.layout.gr_ubersicht);
    checkDbVersionOnAndroid();

Also hier der abruf von checkDbVersionOnAndroid(), dies funktioniert einwandfrei (denke ich mal)

}
void checkDbVersionOnAndroid(){

    try {
        dialog = ProgressDialog.show(rechner.this, "Datenbank", "Überprüfung...");
        myDB = this.openOrCreateDatabase(MY_DB_NAME, MODE_PRIVATE, null);
        myDB.execSQL("CREATE TABLE IF NOT EXISTS " + MDT_version
                + " ( "
                + version_nr + " varchar(10) "
                + ");");
        dialog.dismiss();

    } finally {
         if (myDB != null){

             Toast.makeText(getBaseContext(), "Datenbank gefunden", Toast.LENGTH_SHORT).show(); 

            /*String sql = "INSERT INTO "+ MDT_version +" (version_nr) " +
                        "VALUES (0)";


             myDB.rawQuery(sql, null); */



             myDB.close(); 
             checkInternetDb.start(); 



         }

Diese finally benutze ich zum ersten mal, der sqlite insert ignorieren, da kommt dan was anderes hin (ich habe hier das versucht was Sven mir versuchte zu vermitteln??? (checkInternetDb.start(); ))

    }

}


 Thread checkInternetDb = new Thread(new Runnable(){
                 public void run(){
                    checkMysqlVersionNr(); 
                 }
             });

Und wenn ich das richtig verstandenhabe gehört das hier oben hin?????

Nun kommen wir zum Problem, die funktion soll über php mir die aktuelle versions-nr herausfinden.

protected void checkMysqlVersionNr(){
    Log.i("cmvn","angekommen");
    InputStream is = null;
    StringBuilder sb=null;
    String result=null;
    String id_lieferant = "1";
    if(! isNetworkAvailable()){
     AlertNoInternetOldDb();
 }else{
    Log.i("Internetaviable","angekommen");

    try{        dialog = ProgressDialog.show(rechner.this, "Datenbank", "Version Überprüfung...");  
                HttpClient httpclient=new DefaultHttpClient();
                HttpPost httppost= new HttpPost("mysql_check_version_nr.php"); // make sure the url is correct.
                //add your data
                nameValuePairs = new ArrayList<NameValuePair>(1);
                //String id_lieferant = getid_lieferant(this);
              Log.i("id_lieferant","id_lieferant is " + id_lieferant);
                // Always use the same variable name for posting i.e the android side variable name and php side variable name should be similar, 
                nameValuePairs.add(new BasicNameValuePair("id_lieferant",id_lieferant.toString().trim()));  // $Edittext_value = $_POST['Edittext_value'];
                httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
                //Execute HTTP Post Request
                 HttpResponse response=httpclient.execute(httppost);
                 HttpEntity entity = response.getEntity();
                 is = entity.getContent();
            }catch(Exception e){
                Log.e("log_tag", "Error in http connection"+e.toString());
            }

            //convert response to string
            try{
                InputStreamReader iSR = new InputStreamReader(is,"UTF-8");
                BufferedReader reader = new BufferedReader(iSR,8);
                sb = new StringBuilder();
                Log.i("isr",iSR.toString());
                sb.append(reader.readLine());
                String line="0";

                while ((line = reader.readLine()) != null) {
                    sb.append(line );
                    Log.d("lineNotNull","line"+line);
                }

                is.close();
                result=sb.toString();
               Log.i("result","result"+result);
               Log.i("resultToString","result"+result.toString());

            }catch(Exception e){
                Log.e("log_tag", "Error in read"+e.toString());
            }
            //convert response to string
     try{

             dialog.dismiss();

                SQLiteDatabase db  = this.openOrCreateDatabase(MY_DB_NAME, MODE_PRIVATE, null);

                // 2. build query
                Cursor c = db.rawQuery("SELECT * FROM " + MDT_version, null);
                String version_nr = c.getString(c.getColumnIndex("version_nr"));



                Log.i("db_version_nr","Version Nr ist = "+ version_nr );





             if (c.equals(result) ) {
                 Toast.makeText(getBaseContext(), "Datenbank Aktuell", Toast.LENGTH_LONG).show();
             }else{
                 Toast.makeText(getBaseContext(), "Datenbank Veraltet", Toast.LENGTH_LONG).show();
                 AlertDialog.Builder builder = new AlertDialog.Builder(this);
                 builder.setMessage("Möchten Sie Ihre Datenbank jetzt aktualisieren?").setPositiveButton("Yes", dialogClickListener)
                     .setNegativeButton("No", dialogClickListener).show(); 

             }
             c.close();

        }catch(Exception e){
            Log.e("log_tag", "SQL DB_fehler"+e.toString());
        }
    }
}
///CHECK INTERNET
    public void AlertNoInternetOldDb(){
         rechner.this.runOnUiThread(new Runnable() {
                public void run() {
                    AlertDialog.Builder builder = new AlertDialog.Builder(rechner.this);
                    builder.setTitle("Keine Internetverbindung.");
                    builder.setMessage("Ihre Datenbank könnte veraltet sein.")  
                           .setCancelable(false)
                           .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                               public void onClick(DialogInterface dialog, int id) {
                               }
                           });                     
                    AlertDialog alert = builder.create();
                    alert.show();               
                }
            });
    }
    private boolean isNetworkAvailable() {
        ConnectivityManager connectivityManager 
              = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
        return activeNetworkInfo != null && activeNetworkInfo.isConnected();
    }

Antworten
Volkan Aydin
  • Forum-Beiträge: 187

11.05.2014, 13:56:58 via Website

hmmmmm.... jetzt wenn ich das über den emulator laufen lase kommt nun eine andere fehlermeldung?!

05-11 11:53:22.484: E/log_tag(1485): Error in http connectionjava.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
05-11 11:53:22.484: E/log_tag(1485): Error in readjava.lang.NullPointerException: lock == null
05-11 11:53:22.604: I/Choreographer(1485): Skipped 52 frames! The application may be doing too much work on its main thread.
05-11 11:53:22.674: E/log_tag(1485): SQL DB_fehlerandroid.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 0
05-11 11:53:23.094: W/EGL_emulation(1485): eglSurfaceAttrib not implemented

Antworten
Volkan Aydin
  • Forum-Beiträge: 187

11.05.2014, 14:29:27 via Website

okokok!!!! ich habe gerade herausgefunden wenn ich

dialog = ProgressDialog.show(rechner.this, "Datenbank", "Version Überprüfung...");

Rausnehme funktioniert der code....... um es nicht unnötig kompliziert zu machen nehme ich den raus..... würde aber trotzdem gerne wiessen wie ich diesen trotzdem dort starten könnte?.... Ansonsten schon mal vielen dank für eure mühe..

Antworten
impjor
  • Forum-Beiträge: 1.793

11.05.2014, 21:59:29 via App

Wie oben schon erwähnt, dürfen UI-Elemente (Views, Layout, dein ProgressDialog) nur im UI-Thread verändert werden. Du hast aber einen neuen Thread gestartet.
Stattdessen kannst du hier runOnUiThread() verwenden:
runOnUiThread(new R...{
new ProgressDialog....
});

— geändert am 11.05.2014, 22:00:17

Liebe Grüße impjor.

Für ein gutes Miteinander: Unsere Regeln
Apps für jeden Einsatzzweck
Stellt eure App vor!

Antworten
Volkan Aydin
  • Forum-Beiträge: 187

11.05.2014, 22:22:28 via Website

danke! langsam kapiere ich das ganze mit diesen Thread() zeugs.. is schon was ganz anderes als php oder javascript :)......

Ich bin aber bereits an einem ganz anderem Problem ;) wenn ich es bis morgen nicht schaffe werdet ihr von mir hören ;)

Da möchte ich aber gerne noch eins Wissen.... das ganze ist ja eigentlich Java... lohnt es sich zuerst ein paar Javatutorials zu machen, oder bringen die für Android nur im ansatzt was, weil ich weiss, ich habe das mit diesen Treads mal "gelernt"? Das Grundgerüst von Java hab ich mir vor langer Zeit mal angetan aber eben nie was ernsthaftes zusammengebastelt, deshalb bin ich mir nicht sicher ob ich bei dieser App ne kurze pause machen soll....

Immerhin bastle ich seit ich diesen Fehler behoben habe nur an einem Problem herum... ich will einfach einen String den ich vergleichen kann mit einer SQLite tabelle/... keinen Array, keine Listview.. keine ach was zum teuel auch immer.... :) aber dazu erst morgen ;)

Antworten
Georg C.
  • Forum-Beiträge: 235

12.05.2014, 01:51:34 via Website

Hallo, - versuche es kurz,

*

Da möchte ich aber gerne noch eins Wissen.... das ganze ist ja
eigentlich Java... lohnt es sich zuerst ein paar Javatutorials zu
machen, oder bringen die für Android nur im ansatzt was, weil ich
weiss, ich habe das mit diesen Treads mal "gelernt"? Das Grundgerüst
von Java hab ich mir vor langer Zeit mal angetan aber eben nie was
ernsthaftes zusammengebastelt, deshalb bin ich mir nicht sicher ob ich
bei dieser App ne kurze pause machen soll....
*

ohne es (Android als Embedded System) zu vertiefen, bzw. -> was das Android- API mit sich hat, werde ich sagen;

  • wenn Du (sage ich mal nur wenigstens) Semi- Profi Apps progen möchtest, ist Java ein MUSS!
  • je mehr Du sich mit der Android API auseinander setzt / lernst (die API muss man LERNEN!), desto leichter wir Dir bei Umsetzung seiner eigenen Ideen gehen.
  • ohne Java Programmierung & Android API- Kenntnissen, wirst Du immer ein App- Tüftler sein. (Ist übrigens zum Volkssport geworden!)
  • ob es sinn macht - Android API lernen ohne Java Programmierungskenntnisse; werde ich bezweifeln. Bring nichts.

Was:

langsam kapiere ich das ganze mit diesen Thread() zeugs.. is schon was
ganz anderes als php ...

betrifft:
Ich versuche es (aber Bitte es Bildlich zu interpretieren!)
Ein Thread ist eine Art php Session welche aber einen Request Prozess / Dienst in sich integriert. (Programmierer - bitte es Visual / Bildlich zu betrachten!)

LG
Georg

PS.
Das Code Parse Problem ist schon lange her (ignoriert), auch andere "Sachen" sind nicht schön hier!
...
Aber sonnst ... ist alles OK.

— geändert am 12.05.2014, 01:58:37

Sorry für Gramatik & Stilistik Fehler.

Antworten