Autore Topic: openStream() su url causa crash applicazione  (Letto 631 volte)

Offline wellsaid

  • Nuovo arrivato
  • *
  • Post: 2
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy Tab 2 10.1
  • Sistema operativo:
    Ubuntu 13.04
openStream() su url causa crash applicazione
« il: 19 Agosto 2013, 20:08:59 CEST »
0
Ciao a tutti,
Sono nuovo del forum, del linguaggio java e del sistema operativo android dal punto di vista dello sviluppo, quindi perdonatemi eventuali gaffe.
Sto sviluppando una delle mie primissime applicazioni android e ad un certo punto l'utente deve scrivere in una textView un url e una volta premuto un tasto devo controllare che non ci siano errori nella url. Così prendo la String contenente l'url e lo passo a questa funzione:

Codice (Java): [Seleziona]
        public String erroriURL(String url_str){
                try{
                         URL url = new URL(url_str);
                         InputStreamReader webstream = new InputStreamReader(url.openStream());                  
                         return "";
                }
                catch (IOException e){
                        return "- Errore url: " + e.getMessage();
                }
        }

Alla riga 4 si blocca sempre con un eccezione molto generica che non mi aiuta proprio... Ecco il file log:

Codice: [Seleziona]
08-19 17:57:42.878: W/dalvikvm(877): threadid=1: thread exiting with uncaught exception (group=0x40a71930)
08-19 17:57:42.928: E/AndroidRuntime(877): FATAL EXCEPTION: main
08-19 17:57:42.928: E/AndroidRuntime(877): java.lang.IllegalStateException: Could not execute method of the activity
08-19 17:57:42.928: E/AndroidRuntime(877):         at android.view.View$1.onClick(View.java:3599)
08-19 17:57:42.928: E/AndroidRuntime(877):         at android.view.View.performClick(View.java:4204)
08-19 17:57:42.928: E/AndroidRuntime(877):         at android.view.View$PerformClick.run(View.java:17355)
08-19 17:57:42.928: E/AndroidRuntime(877):         at android.os.Handler.handleCallback(Handler.java:725)
08-19 17:57:42.928: E/AndroidRuntime(877):         at android.os.Handler.dispatchMessage(Handler.java:92)
08-19 17:57:42.928: E/AndroidRuntime(877):         at android.os.Looper.loop(Looper.java:137)
08-19 17:57:42.928: E/AndroidRuntime(877):         at android.app.ActivityThread.main(ActivityThread.java:5041)
08-19 17:57:42.928: E/AndroidRuntime(877):         at java.lang.reflect.Method.invokeNative(Native Method)
08-19 17:57:42.928: E/AndroidRuntime(877):         at java.lang.reflect.Method.invoke(Method.java:511)
08-19 17:57:42.928: E/AndroidRuntime(877):         at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
08-19 17:57:42.928: E/AndroidRuntime(877):         at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
08-19 17:57:42.928: E/AndroidRuntime(877):         at dalvik.system.NativeStart.main(Native Method)
08-19 17:57:42.928: E/AndroidRuntime(877): Caused by: java.lang.reflect.InvocationTargetException
08-19 17:57:42.928: E/AndroidRuntime(877):         at java.lang.reflect.Method.invokeNative(Native Method)
08-19 17:57:42.928: E/AndroidRuntime(877):         at java.lang.reflect.Method.invoke(Method.java:511)
08-19 17:57:42.928: E/AndroidRuntime(877):         at android.view.View$1.onClick(View.java:3594)
08-19 17:57:42.928: E/AndroidRuntime(877):         ... 11 more
08-19 17:57:42.928: E/AndroidRuntime(877): Caused by: android.os.NetworkOnMainThreadException
08-19 17:57:42.928: E/AndroidRuntime(877):         at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1117)
08-19 17:57:42.928: E/AndroidRuntime(877):         at java.net.InetAddress.lookupHostByName(InetAddress.java:385)
08-19 17:57:42.928: E/AndroidRuntime(877):         at java.net.InetAddress.getAllByNameImpl(InetAddress.java:236)
08-19 17:57:42.928: E/AndroidRuntime(877):         at java.net.InetAddress.getAllByName(InetAddress.java:214)
08-19 17:57:42.928: E/AndroidRuntime(877):         at libcore.net.http.HttpConnection.<init>(HttpConnection.java:70)
08-19 17:57:42.928: E/AndroidRuntime(877):         at libcore.net.http.HttpConnection.<init>(HttpConnection.java:50)
08-19 17:57:42.928: E/AndroidRuntime(877):         at libcore.net.http.HttpConnection$Address.connect(HttpConnection.java:340)
08-19 17:57:42.928: E/AndroidRuntime(877):         at libcore.net.http.HttpConnectionPool.get(HttpConnectionPool.java:87)
08-19 17:57:42.928: E/AndroidRuntime(877):         at libcore.net.http.HttpConnection.connect(HttpConnection.java:128)
08-19 17:57:42.928: E/AndroidRuntime(877):         at libcore.net.http.HttpEngine.openSocketConnection(HttpEngine.java:316)
08-19 17:57:42.928: E/AndroidRuntime(877):         at libcore.net.http.HttpEngine.connect(HttpEngine.java:311)
08-19 17:57:42.928: E/AndroidRuntime(877):         at libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:290)
08-19 17:57:42.928: E/AndroidRuntime(877):         at libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:240)
08-19 17:57:42.928: E/AndroidRuntime(877):         at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:282)
08-19 17:57:42.928: E/AndroidRuntime(877):         at libcore.net.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:177)
08-19 17:57:42.928: E/AndroidRuntime(877):         at java.net.URL.openStream(URL.java:462)
08-19 17:57:42.928: E/AndroidRuntime(877):         at com.aggiornax3.AddActivity.erroriURL(AddActivity.java:63)
08-19 17:57:42.928: E/AndroidRuntime(877):         at com.aggiornax3.AddActivity.okButtonHandler(AddActivity.java:97)
08-19 17:57:42.928: E/AndroidRuntime(877):         ... 14 more

Cercando su google, ho trovato tre soluzioni che per me non hanno funzionato:
1. Impostare i permessi per accedere al web sul file Manifest.xml
2. Usare i Thread
3. Creare un'ulteriore activity che faccia questo lavoro

Ho testato l'applicazione sia sull'emulatore che c'è su eclipse con android 4.1 che sul mio Samsung Galaxy Tab 2 10.1 con Android 4.0

Come posso fare a risolvere?

Grazie in anticipo per le risposte  ;-)

Offline bradipao

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 4043
  • keep it simple
  • Respect: +567
    • Github
    • Google+
    • bradipao
    • Mostra profilo
  • Dispositivo Android:
    Nexus 5
  • Play Store ID:
    Bradipao
  • Sistema operativo:
    W7
Re:openStream() su url causa crash applicazione
« Risposta #1 il: 20 Agosto 2013, 09:00:01 CEST »
0
E' un errore tra i più gettonati e la soluzione 2 dovrebbe risolvere il tuo problema.

Citazione
08-19 17:57:42.928: E/AndroidRuntime(877): Caused by: android.os.NetworkOnMainThreadException

Questa exception segnala che stai facendo la connessione di rete nel thread principale (quello di UI). In android 2.x era teoricamente possibile ma fortemente sconsigliato, adesso viene proprio segnalato come errore e sollevata la suddetta eccezione.

Le connessioni di rete devono essere eseguite in thread/asynctask separati. Se hai già provato e fallito, posta il codice che hai provato.
NON rispondo a domande nei messaggi privati
Bradipao @ Play Store

Offline wellsaid

  • Nuovo arrivato
  • *
  • Post: 2
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy Tab 2 10.1
  • Sistema operativo:
    Ubuntu 13.04
Re:openStream() su url causa crash applicazione
« Risposta #2 il: 20 Agosto 2013, 21:09:28 CEST »
0
Ciao,
Alla fine sono riuscito ad usare questi benedetti Thread, la funzione è questa:

Codice (Java): [Seleziona]
        public void erroriURL(final String url_str){
                erroriURL_ret = "";
               
                new Thread(new Runnable() {
                public void run() {
                        try{
                                URL url = new URL(url_str);
                                HttpURLConnection c = (HttpURLConnection) url.openConnection();
                        c.setRequestProperty("User-Agent", "userAgent");
                        c.connect();
                        int responseCode = c.getResponseCode();
                        if (responseCode == 404) {
                                erroriURL_ret += "Errore url - 404 page cannot be found";
                        }
                                }
                                catch (Exception e){
                                        erroriURL_ret += "- Errore url: " + e.getMessage();
                                }
                }
            }).start();
        }


E ho dovuto aggiungere questa riga nel manifest.xml:
Codice (XML): [Seleziona]
<uses-permission android:name="android.permission.INTERNET" />
Grazie per la risposta  :-)

EDIT:
Se dovesse servire a qualcuno:
Questo codice mi dava dei problemi perchè dava sempre errori diversi all'utente, questo ha funzionato meglio:

1. Ho creato questa classe all'interno del mio package:
Codice (Java): [Seleziona]
package com.aggiornax3;

import java.net.HttpURLConnection;
import java.net.URL;

import android.os.AsyncTask;

class NetworkClass extends AsyncTask<String, Void, String> {

        protected String doInBackground(String... urls) {
        try {
                URL url = new URL(urls[0]);
                HttpURLConnection c = (HttpURLConnection) url.openConnection();
            c.setRequestProperty("User-Agent", "userAgent");
            c.connect();
                return "";
        } catch (Exception e) {
            return e.getMessage();
        }
    }
   
}

2.E l'ho chiamata in questo modo nella mia activity principale:
Codice (Java): [Seleziona]
                NetworkClass nwc = new NetworkClass();
                try {
                        err += nwc.execute(url_str).get();
                } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                } catch (ExecutionException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                }
« Ultima modifica: 24 Agosto 2013, 13:21:13 CEST da wellsaid »