Datenkommunikation mit HTTP Server

  • 4 Antworten
  • Letztes Antwortdatum
C

Chris-Pi

Neues Mitglied
0
Hallo zusammen,

ich bin neu hier und möchte mich kurz Vorstellen - ich studiere Elektrotechnik und mache derzeit ein Praktikum in China - dort muss ich ein Projekt bearbeiten welches in Android realisiert werden soll.

Da fangen auch schon meine Probleme an, ich habe in meinem Leben bisher nur C und C++ Vorlesungen besucht und eigentlich von praktischer Programmierung keine Ahnung, da ich auch kein Informatiker bin - aber Anfangen muss man ja bekanntlich irgendwie mal.

Ich habe folgende Aufgabe;

Eine App soll Daten von einer Datenbank aus dem Netz holen und anzeigen - sicherlich recht easy für die meisten, nicht für mich :flapper:

Ich habe mich schon eine ganze Weile belesen, wie man sowas am besten Realisiert.

Dabei bin ich oft auf folgenden Ansatz gestoßen...

Android App <-> php Skript <-> DB

Als Parser für die Daten habe ich oft das Wort "JSON" gefunden und mir auch schon entsprechende Biblotheken angeschaut.

Die Idee habe ich also soweit verstanden und im Kopf, was meint ihr dazu?

Nun ans praktische:

Ich wollte mir erstmal eine App zum Testen bauen, die mir einen einfachen String von einem php File anzeigt, damit ich schauen kann, ob meine Verbindung funktioniert - Schritt für Schritt sozusagen.

Da ich wie gesagt gar keine Ahnung von Programmierung habe, habe ich ein paar Tutorials im Internet gesucht, mir den Code kopiert, angepasst und versucht diesen Nachzuvollziehen - das hat auch ganz gut geklappt.

Bevor es zum Code geht, bitte erschlagt mich nicht dafür, wie das aussieht - bin blutiger Anfänger und habe vieles Kopiert - für mich ist Wichtig zu verstehen, was dort passiert - das ist mir bisher auch ganz gut gelungen, zumindest zum Großteil ;-)

Die erste Klasse ist meine Activity, die beim Starten nur ein Objekt vom Typ ConnectionHttp erstellt und eine Methode davon aufruft.

Code:
public class ActivityData extends Activity {
	
	@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_activity_data);
        
        ConnectionHttp ConnectionHttp_Instanz = new ConnectionHttp (this);
        
        ConnectionHttp_Instanz.getData();
        
     
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_activity_data, menu);
        return true;
        
    }   
       
}

Die Klasse ConnectionHttp erstellt die Verbindung zum Server, das habe ich in einem Tutorial gefunden.

Code:
public class ConnectionHttp {
	  
	private final String TAG = ActivityLogin.class.getSimpleName();
	private final String url = "http://192.168.1.107/test1.php";
	
	// Konstruktor
	
	public ConnectionHttp(Activity activityData)
	{
		activity = activityData;
	}
	// Activity Member fuer aktuelle GUI -> AcitivityData -> notwendig fuer Meldungen auf GUI
	private Activity activity;

	// HTTP
    
    public void getData()
    {
  
    	//der HttpClient dient dazu die Anfrage an den Server zu stellen
        HttpClient client = new DefaultHttpClient();

        //Art der Anfrage
        HttpGet httpGet = new HttpGet(url);

        //Antwort des Severs
        HttpResponse response = null;
        

        try {
            //ausführen der Anfrage
            response = client.execute(httpGet);

        } catch (ClientProtocolException e) {
            Log.e(TAG,"Falsches Protokol " + " " + e.getMessage());
        } catch (IOException e) {
            Log.e(TAG,"URL ist falsch, URL:"+ url + " " + e.getMessage());
        }

        //Kontrolle ob bei ausführen der Anfrage ein Fehler aufgetreten ist
        if(response != null){

            //Status der Abfrage 
            StatusLine statusLine = response.getStatusLine();

            //Statuscode 200 => Die Anfrage wurde erfolgreich bearbeitet und das Ergebnis der Anfrage wird in der Antwort übertragen 
            if(statusLine.getStatusCode() == 200) {

                //Ergebnis der Anfrage
                HttpEntity entity = response.getEntity();

                try {
                    //Start des Hintergrundprozess um zu parsen -> neue ReadData Instanz erzeugen
                	// Übergabe der derzeitigen GUI als activity
                    new ReadData(activity).execute(entity.getContent());

                } catch (IllegalStateException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            else{
               Toast.makeText(activity,"Der Server antwortet mit anderen Statuscode als 200. Statuscode: "+statusLine.getStatusCode(), Toast.LENGTH_SHORT).show();
            }
        }
        else{
            Toast.makeText(activity,"Keine Internetverbindung.", Toast.LENGTH_SHORT).show();
        }
    }

}

Wenn der HTTP Zugriff erfolgreich war, wird ein Objekt vom Typ ReadData erzeugt, dieses soll dann die Daten auch wirklich verarbeiten.

Code:
public class ReadData extends AsyncTask<InputStream, Void, Void> {

		
	// Anzeige das vom Server geladen wird

	private ProgressDialog dialog;	
	private String TestString;
	private Activity activity1;

	// Konstruktor
	public ReadData(Activity activity) 
	{
		dialog = new ProgressDialog(activity);
		activity1 = activity;
	}

	// wird VOR onInBackground ausgeführt

	protected void onPreExecute() 
	{
		// einrichten des Wartedialogs
		this.dialog.setTitle("Bitte warten!");
		this.dialog.setMessage("Daten werden geladen");
		this.dialog.show();
	}

	// Aktion im Hintergrund

	protected Void doInBackground(InputStream... inputStreams)
	{
		// Hier Aktion fuer Hintergrund	
		return null;
	}

	// Aktion NACH Ausführung

	protected void onPostExecute(Void result)

	{
		// Dialog beenden
		if (dialog.isShowing()) {
			dialog.dismiss();
		}
		// Write to Text
	}
}


Das ist, was ich bisher so habe.

Mein Problem, ich weiss jetzt nich so recht wie ich den InputStream verarbeiten kann. Ich habe ein wenig gegoogled nach InputStream to String, ist dies das richtige Stichwort?

Ein weiteres Problem, ich möchte gerne in einem einfachen TextView den Inhalt des Strings darstellen, aber wie mache ich das außerhalb der Activity?

Ich habe gedacht, ich kann in der Acitivty eine Methode zum Beschrieben der TextView erstellen, aber ich weiss ja nicht wie die Instanz der Activity heißt.

Mhm, sicher viele Fragen - die zeigen welchen Kenntniss-Stand ich habe, gar keinen :)

Es wäre trotzdem schön, wenn sich jemand ein wenig Zeit nehmen könnte und entsprechend meinem Niveau helfen könnte, angefangen haben wir schließlich alle mal - ich möchte das ganze nämlich auch ein wenig verstehen und die meisten Links zu Tutorials oder Foreneinträgen sind mir oft zu hoch, da mir dazu einfach das Know-How fehlt.

Eine weitere Frage noch:

"public class ReadData extends AsyncTask<InputStream, Void, Void>"

Ich kenne leider die Syntax mit den Parametern hinter dem Klassen-Namen,
(Asynctask) gar nicht und bin mir über die Bedeutung auch nich bewusst. Was hat es also damit auf sich? Konnte dazu auch leider nichts finden...

Danke schonmal falls sich jemand die Zeit nimmt.

Beste Grüße
 
das mit der Activity - du wirst doch wissen wo du dich gerade befindest, sprich in welcher activity du dein http zeug machst. wenn in dieser klasse auch deine activity ist kannst du dort doch deine textview ansprechen und weiter verarbeiten?! das Async brauchst du um Daten zu manipulieren, seit Android 3.0 ist das so. Weil du sonst den UI Thread blockierst und das würde dazu führen das deine App abstürzt
 
Das Problem ist sozusagen, ich mache das http Zeug aber außerhalb der Activity in einer anderen Klasse - das ist irgendwie so das Problem.

Das Resultat steht ja in der Klasse "DataSend", aber wie bekomme ich das jetzt von da, auf die textView?

Ich vermute die Lösung ist einfach, aber ich weiss es nicht :)
 
du rufst doch die methode getData auf, anstatt da void als Rückgabe zu definieren, definierst du dein gewünschtes Objekt als Rückgabeparameter ;) und gibst es natürlich auch zurück ...
 
Ja also, den Gedanken hatte ich auch schon, liegt ja auch auf der Hand.

Aber so richtig wollte das nicht klappen - ich hatte dann immer "null" als String Ergebniss, ich gehe davon aus, das die Ausgabe des Strings dann vor der fertigstellung des Tasks erfolgt ist - liegt ja auch auf der Hand.

Ich habe es jetzt so gelöst, ich habe einfach das TextView im Konstruktor mitgegeben und direkt von onPostExecute darauf geschrieben.

Das ist sicher eine schlechte Lösung - daher, wie genau würde man das mit dem Rückgabewert bei getData() Lösen, so das die Aktualisierung vom TextView erst nach der Abarbeitung des Threads erfolgt?

Stehe ein wenig auf dem Schlauch.

Danke!

Beste Grüße
 
Zurück
Oben Unten