Benötige Hilfe beim Beheben eines beim Versuch eine Webseite mit einem BufferReader und InputStreamReader auftretendem Fehler!

  • Antworten:14
  • OffenNicht stickyBentwortet
  • Forum-Beiträge: 21

29.05.2016, 12:23:06 via Website

Beim Ausführen dieser Funktion (string path ist beim Ausführen eine valide Url einer Webseite)

public String[] getData(String path){
String[] data = new String[0]; `

    URL url;

    try {
        url = new URL(path);
        URLConnection conn = url.openConnection();

        BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));

        ArrayList<String> tempData = new ArrayList<String>();

        String line;

        while((line = br.readLine()) != null){
            tempData.add(line);
        }

        data = (String[]) tempData.toArray();

        Log.d("MainActivity", "getData() : Success to get content! Could get: " + path);
    } catch(IOException ex) {
        data[0] = "";
        Log.d("MainActivity", "getData() : Failed to get content! Could not get: " + path);
    }

    return data;
} 

tritt dieser Fehler auf:

05-29 10:14:12.602 1628-1628/de.gymoth.gymothapp E/AndroidRuntime: FATAL EXCEPTION: main
Process: de.gymoth.gymothapp, PID: 1628
java.lang.RuntimeException: Unable to start activity ComponentInfo{de.gymoth.gymothapp/de.gymoth.gymothapp.MainActivity}: android.os.NetworkOnMainThreadException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: android.os.NetworkOnMainThreadException
at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1273)
at java.net.InetAddress.lookupHostByName(InetAddress.java:431)
at java.net.InetAddress.getAllByNameImpl(InetAddress.java:252)
at java.net.InetAddress.getAllByName(InetAddress.java:215)
at com.android.okhttp.internal.Network$1.resolveInetAddresses(Network.java:29)
at com.android.okhttp.internal.http.RouteSelector.resetNextInetSocketAddress(RouteSelector.java:188)
at com.android.okhttp.internal.http.RouteSelector.nextProxy(RouteSelector.java:157)
at com.android.okhttp.internal.http.RouteSelector.next(RouteSelector.java:100)
at com.android.okhttp.internal.http.HttpEngine.createNextConnection(HttpEngine.java:357)
at com.android.okhttp.internal.http.HttpEngine.nextConnection(HttpEngine.java:340)
at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:330)
at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:248)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:433)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:384)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:231)
at de.gymoth.gymothapp.MainActivity.getData(MainActivity.java:55)
at de.gymoth.gymothapp.MainActivity.generateVertretungsplan(MainActivity.java:30)
at de.gymoth.gymothapp.MainActivity.onCreate(MainActivity.java:26)
at android.app.Activity.performCreate(Activity.java:6237)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476) 
at android.app.ActivityThread.-wrap11(ActivityThread.java) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:148) 
at android.app.ActivityThread.main(ActivityThread.java:5417) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 
05-29 10:14:19.268 1628-1628/de.gymoth.gymothapp I/Process: Sending signal. PID: 1628 SIG: 9

— geändert am 29.05.2016, 12:24:19

Antworten
Pascal P.
  • Mod
  • Blogger
  • Forum-Beiträge: 10.170

29.05.2016, 12:29:44 via Website

Hallo Jonah,
Du darfst Netzwerkoperationen nicht im Mainthread machen.
Nutze einen Thread oder besser einen AsyncTask dafür.

Schau hier: https://www.androidpit.de/forum/568854/tutorial-download-einer-webseite

Aber das ganze kannst du dir sparen, indem du zum laden der Webseite eine HTTP lib benutzt wie z.b. ION,Volley,OkHttp etc..

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
  • Forum-Beiträge: 21

29.05.2016, 12:57:58 via Website

Schon mal danke für deine Antwort, ich denke ich werde
mich mal mit einer von den vorgeschlagenen http libs beschäftigen.

Antworten
Gelöschter Account
  • Forum-Beiträge: 72

29.05.2016, 16:47:52 via Website

Jonah H.

Schon mal danke für deine Antwort, ich denke ich werde
mich mal mit einer von den vorgeschlagenen http libs beschäftigen.

Hi,

ich hab schon mal vor langer Zeit in Java einen Webserver und Browser programmiert. Dein Ansatz funktioniert so nicht. Wenn du den Datenstrom selber parsen willst, musst du das HTTP-Protokoll studieren. Das ist ein Zeilenorientiertes Text-Protokoll. Denn im HTTP Header könnte auch stehen dass der BODY mit einem Algorithmus gepackt sein kann und eventuelle Binärdaten wie zum Beispiel Bilder enthalten sein können. Außerdem musst du dem Server zuerst einen Header schicken bevor der dir die Seite zurück schickt. Das ist alles sehr kompliziert.

Ein sehr einfacher weg ist es mit der klasse Document die Seite zu laden und mit der klasse TextEdit anzeigen zu lassen. Damit umgehst du den ganzen HTTP Mist.

Was ist eigentlich dein Ziel?

Grüße

— geändert am 29.05.2016, 16:52:19

Antworten
  • Forum-Beiträge: 21

29.05.2016, 18:50:20 via Website

Eigentlich brauche ich von der Webseite lediglich den Text, die XML Tags aus der HTML Seite werden also nach dem ich die Array habe gelöscht,
dies mache ich weil ich für meine Schule (bzw. den Informatik Kurs, bin in der 10. Klasse) eine Android App programmieren möchte die den Vertretungsplan der Schule für die jeweiligen Klassen filtert und dann ausgibt, dies habe ich schon in PHP Form gemacht aber das ist nicht gerade praktisch fürs Handy. Momentan versuche ich es mit ION und ich kann die HTML Datei lesen aber nicht ganz habe ich das Gefühl denn wenn ich die Text Version ausgeben lasse im Log wird ungefähr die hälfte des Source Codes nicht gezeigt.

Antworten
Pascal P.
  • Mod
  • Blogger
  • Forum-Beiträge: 10.170

29.05.2016, 18:59:57 via Website

Um welchen Vertratungsplanbetreiber handelt es sich?
Eventuell DSB?
Da könnte ich weiterhelfen :P

Sonst:
Da ich das gleiche auch mit PHP gemacht habe, habe ich das PHP zum Vertretungsplan Filtern so umstrukturiert, dass es eine Desktop View und MobileView hat, sodass die HTML an den mobilen Client angepasst ist.

Sonst HTML als String laden und dann die einzelnen Tags am besten mit z.b. Jsoup parsen. DAmit kannst du auch direkt den Text extrahieren.
Aber wenn du es filter wollst, ist das parsen der Tags, und das konvertieren in eigene Objekte, welche du dann Filtern kannst besser

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
  • Forum-Beiträge: 21

29.05.2016, 19:04:42 via Website

Ich denke das unser Vertretungsplan eher "primitiv" ist www.gymoth.de/plan.php :D

Antworten
Pascal P.
  • Mod
  • Blogger
  • Forum-Beiträge: 10.170

29.05.2016, 19:39:26 via App

Ok stimmt :)

Da kannste eigentlich den Text nehmen.
Aber eventuell erleichtert dir Jsoup trotzdem die Arbeit.
Alternativ kannst du mal deinen Info Lehrer fragen ob es möglich währe den plan als Json oder xml zur verfüung zu stellen dann ista noch einfacher.
Oder du machst das mit deinem PHP selber.
Ich denke du bekommst das schon hin, lass dich von meinen Ideen nicht allzu ablenken xD

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
Gelöschter Account
  • Forum-Beiträge: 72

29.05.2016, 20:05:13 via Website

Jonah H.

Eigentlich brauche ich von der Webseite lediglich den Text

Ok, ich nehme einmal an, dass du den Source code direkt von der Webseite beziehen möchtest? Dies ist aber nicht einfach da du dich dann mit dem HTTP-Protokoll befassen musst. Wenn du den Quellcode im Webbrowser anschaust ist der bereits gefiltert (je nach Browser) du siehst da meistens nicht alles (und das HTTP Protokolll schon gar nicht). Wie ich oben schon geschrieben hab ist es das einfachste wenn du die Dokument-Klasse verwendest Da kannst du eine URI (URL kann man umwanden) angeben. Damit steht dir dann der Source-Code zur Verfügung den du dir mit der Klasse TextEdit und dem Datentyp "text/plain" anzeigen lassen kannst. Hast du das geschafft, ziehst du aus dem Code mit Regular Expression das raus was du brauchst.

Grüße

PS: die Klasse TextEdit ist ein kompletter Multimedia Browser :)

— geändert am 29.05.2016, 20:14:33

Antworten
Pascal P.
  • Mod
  • Blogger
  • Forum-Beiträge: 10.170

29.05.2016, 20:07:47 via Website

@Bernhard:
Mach es doch nicht so kompliziert.
Ein http Request per HttpUrlConnectiom acht doch schon alles.
Zudem habe ich ihm ja geraten eine Lib zu nehmen, damit gibtst du die Url an und bekommst den Html strign zurück.
Man muss das Rad nicht neu erfinden ;)

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
  • Forum-Beiträge: 21

30.05.2016, 07:25:41 via Website

Ich habs jetzt mehr oder weniger ich kann die Webseite jetzt
in einer Array wiedergeben, aber die Sonderzeichen werden als
� daargestellt, was muss ich mit der String[] machen damit es
funktioniert?

Antworten
Pascal P.
  • Mod
  • Blogger
  • Forum-Beiträge: 10.170

30.05.2016, 07:37:54 via App

Der string muss im passenden Zeichensatz sein. meist utf8

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten

Empfohlene Artikel