2012-02-28 11 views
8

Pracuję nad projektem Android i jestem w punkcie, w którym chcę poprosić niektóre API o informacje. Wydaje się, że to powinno być bardzo proste!HttpResponse za pomocą android wydania: wykonanie zawsze powoduje wyjątek?

Oto ogólny sens mojego kodu:

private InputStream retrieveStream2(String url) 
{ 
    DefaultHttpClient client = new DefaultHttpClient(); 

    HttpGet getRequest = new HttpGet(url); 
    System.out.println("getRequest == " + getRequest); 
    try { 


     HttpResponse getResponse = client.execute(getRequest);//here is teh problem 
     final int statusCode = getResponse.getStatusLine().getStatusCode(); 


     if (statusCode != HttpStatus.SC_OK) 
     { 
      Log.w(getClass().getSimpleName(), 
        "Error " + statusCode + " for URL " + url); 
      return null; 
     } 

     HttpEntity getResponseEntity = getResponse.getEntity(); 
     return getResponseEntity.getContent(); 

    } 
    catch (Exception e) 
    { 
     getRequest.abort(); 
     Log.w(getClass().getSimpleName(), "Error for URL, YO " + url, e); 
    } 
    return null; 
} 

gdzie zmienna url jest łańcuch "http://search.twitter.com/search.json?q=javacodegeeks".

Jak widać, na stronie jest kilka fajnych informacji o JSON; Mój problem polega na tym, że za każdym razem, gdy wywoływany jest '' client.execute (getRequest); '', program wyrzuca i przechwytuje wyjątek. Nieprzydatne!

Słyszałem dwie rzeczy:

1) Musisz ustawić uprawnienia dla emulatora/urządzenia do korzystania z Internetu! - Myślę, że to omówiłem, ale może zrobiłem to źle! W AndroidManifest.xml dodałem

< uses-permission android:name="android.permission.INTERNET" >< /uses-permission> 

Więc nie o to chodzi.

2) (o czym nie jestem przekonany), nie można uruchomić wątku "sieciowego" wewnątrz wątku "ui". Nie jestem do końca pewien, co to oznacza, ale poszedłem do przodu i poszedłem za przykładem samouczka na temat wątków Androida, Handlerów i AsyncTasks. Tutaj: Proszę sprawdzić kod pod tutorialu AsyncTask, którą następnie:

http://www.vogella.de/articles/AndroidPerformance/article.html

Po wykonaniu wraz z samouczka AsyncTask, stwierdziliśmy, że nadal miał ten sam problem--

linię : HttpGet httpGet = new HttpGet (url) zawsze wyrzucał wyjątek, jak poprzednio.

Oto logcat z mojej próbie z samouczka gwintowania powyżej:

02-27 20:43:28.565: I/ActivityManager(92): START {cmp=com.Prometheus.R1/.JsonParsingActivity} from pid 574 
02-27 20:43:28.565: W/WindowManager(92): Failure taking screenshot for (180x300) to layer 21010 
02-27 20:43:28.896: I/System.out(574): pre execute 
02-27 20:43:29.236: I/ActivityManager(92): Displayed com.Prometheus.R1/.JsonParsingActivity: +638ms 
02-27 20:43:29.329: I/ARMAssembler(35): generated scanline__00000077:03010104_00008001_00000000 [ 89 ipp] (110 ins) at [0x40fad6a8:0x40fad860] in 7204915 ns 
02-27 20:43:30.016: W/System.err(574): java.net.UnknownHostException: Unable to resolve host "search.twitter.com": No address associated with hostname 
02-27 20:43:30.016: W/System.err(574): at java.net.InetAddress.lookupHostByName(InetAddress.java:426) 
02-27 20:43:30.026: W/System.err(574): at java.net.InetAddress.getAllByNameImpl(InetAddress.java:242) 
02-27 20:43:30.026: W/System.err(574): at java.net.InetAddress.getAllByName(InetAddress.java:220) 
02-27 20:43:30.026: W/System.err(574): at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:137) 
02-27 20:43:30.036: W/System.err(574): at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164) 
02-27 20:43:30.036: W/System.err(574): at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119) 
02-27 20:43:30.046: W/System.err(574): at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360) 
02-27 20:43:30.046: W/System.err(574): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555) 
02-27 20:43:30.046: W/System.err(574): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487) 
02-27 20:43:30.055: W/System.err(574): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465) 
02-27 20:43:30.055: W/System.err(574): at com.Prometheus.R1.JsonParsingActivity$DownloadWebPageTask.doInBackground(JsonParsingActivity.java:88) 
02-27 20:43:30.055: W/System.err(574): at com.Prometheus.R1.JsonParsingActivity$DownloadWebPageTask.doInBackground(JsonParsingActivity.java:1) 
02-27 20:43:30.055: W/System.err(574): at android.os.AsyncTask$2.call(AsyncTask.java:264)<br/> 
02-27 20:43:30.066: W/System.err(574): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305) 
02-27 20:43:30.066: W/System.err(574): at java.util.concurrent.FutureTask.run(FutureTask.java:137)<br/> 
02-27 20:43:30.066: W/System.err(574): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:208) 
02-27 20:43:30.076: W/System.err(574): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076) 
02-27 20:43:30.076: W/System.err(574): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569) 
02-27 20:43:30.087: W/System.err(574): at java.lang.Thread.run(Thread.java:856) 
02-27 20:43:30.108: W/System.err(574): Caused by: libcore.io.GaiException: getaddrinfo failed: EAI_NODATA (No address associated with hostname) 
02-27 20:43:30.116: W/System.err(574): at libcore.io.Posix.getaddrinfo(Native Method) 
02-27 20:43:30.116: W/System.err(574): at libcore.io.ForwardingOs.getaddrinfo(ForwardingOs.java:55) 
02-27 20:43:30.126: W/System.err(574): at java.net.InetAddress.lookupHostByName(InetAddress.java:411) 
02-27 20:43:30.126: W/System.err(574): ... 18 more 
02-27 20:43:30.136: I/System.out(574): Except thrown by url http://search.twitter.com/search.json?q=javacodegeeks, .... 
02-27 20:43:30.136: I/System.out(574): response = 


Wyjątkiem jest UnknownHostException jak widać:
„ava.net.UnknownHostException: Nie można rozwiązać hosta” search.twitter.com „: Brak adresu powiązany z nazwą hosta”
Ale nie sądzę, że witryna jest niedopuszczalne ...

ktoś może mi powiedzieć, co się dzieje + co muszę d o przejść przez to?

+0

czym są wyjątki i śledzenie stosu? –

+1

Dodałem kod logcat do oryginalnego pytania, ponieważ jest długi. –

+0

Dodanie uprawnień rozwiązało to dla mnie. Ale pamiętaj, aby zmienić tę linię: '' to '' –

Odpowiedz

1

Myślę, że problem tkwi w url masz wskazanym w żądaniu HTTP lub połączenia internetowego pls sprawdzić poniższy link, to pomoże Ci Link

+0

No cóż, nie sądzę, że problem jest w adresie URL, ponieważ kiedy idę do adresu URL na moim komputerze, widzę niezłego brzydkiego 1linera Jsona wypełniającego ekran. Sprawdziłem ten link i próbowałem: System.setProperty ("http.proxyHost", android.net.Proxy.getDefaultHost()); System.setProperty ("http.proxyPort", Integer.toString (proxyPort)); Zrobiłem to na początku mojego zgłoszenia. Naprawdę nie wiem, co robi - ale to nie rozwiązuje problemu; –

+0

Czy problem może występować w ustawieniach mojej sieci? –

10

Zdobione. Najwyraźniej zmieniłem mój AVD z "trybu samolotowego".

Dla każdego, kto ma taki sam problem jak ja, prawdopodobnie korzystasz z łączności bezprzewodowej. Z jakiegoś powodu andriod spogląda na twoją kartę LAN, więc idź do Network Connections i kliknij prawym klawiszem na kartę LAN - DISABLE THING THING! Problem rozwiązany.

+0

MAN! uratowałeś mnie ... utknąłem na logice uprawnień (runtime) i wyszukiwaniu SO, co mogło zawieść wywołanie API ... – bqr

10

Sprawdź uprawnienia swoim manifeście, upewnij się, że zostały dodane to:

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> 
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/> 
<uses-permission android:name="android.permission.INTERNET"/> 
-2

można zezwolić na dostęp do sieci w głównym wątku za pomocą poniższego fragmentu. na początku metody onCreate() twojej aktywności.

StrictMode.ThreadPolicy policy = new StrictMode. 
ThreadPolicy.Builder().permitAll().build(); 
StrictMode.setThreadPolicy(policy); 
+0

Wykonywanie żądań sieciowych w głównym wątku jest bardzo złym pomysłem, spowoduje opóźnienia w renderowaniu UI . To najprawdopodobniej prowadzi do złych recenzji i 1 gwiazdki. –

1

Wpadłem również na ten problem. W moim przypadku używam HttpURLConnection do załadowania JSON. Problem został rozwiązany, gdy włączono opcję "wykonaj przekierowania". Oto fragment kodu, który działa:

HttpURLConnection connection = null; 
    BufferedReader reader = null; 
    String JSON_data = null; 

    try { 
     final int half_hour = 30 * 60; 
     URL fetch = new URL(requestUrl); 
     connection = (HttpURLConnection) fetch.openConnection(); 

     // FIXED: request to follow redirects - this seems to solve networking issues on older devices < API 21 
     connection.setInstanceFollowRedirects(true); 

     connection.setUseCaches(true); 
     connection.setDefaultUseCaches(true); 
     connection.setRequestMethod("GET"); 
     connection.addRequestProperty("Cache-Control", "max-age="+half_hour); 
     connection.addRequestProperty("X-Auth-Token", getString(R.string.api_key)); 

     boolean redirect = false; 
     int status = connection.getResponseCode(); 
     if (status != HttpURLConnection.HTTP_OK) { 
      if (status == HttpURLConnection.HTTP_MOVED_TEMP 
        || status == HttpURLConnection.HTTP_MOVED_PERM 
        || status == HttpURLConnection.HTTP_SEE_OTHER) 
       redirect = true; 
     } 
     Log.d(TAG, "===> HTTP STATUS CODE: " + status + ", redirect=" + redirect); 

     connection.connect(); 

     // Read the input stream into a String 
     InputStream inputStream = connection.getInputStream(); 
     if (inputStream == null) { 
      return; 
     } 

     reader = new BufferedReader(new InputStreamReader(inputStream)); 

     StringBuilder buffer = new StringBuilder(); 
     String line; 
     while ((line = reader.readLine()) != null) { 
      buffer.append(line); 
      buffer.append("\n"); 
     } 
     if (buffer.length() == 0) { 
      return; 
     } 
     JSON_data = buffer.toString(); 
     Log.d(TAG, "JSON_data=" + JSON_data); 
    } catch (Exception e) { 
     // possible UnknownHostException on older Android device? 
     Log.e(TAG, "HttpURLConnection Exception - e=" + e.getMessage()); 
     e.printStackTrace(); 
    } finally { 
     if (connection != null) { 
      connection.disconnect(); 
     } 
     if (reader != null) { 
      try { 
       reader.close(); 
      } catch (IOException e) { 
       Log.e(TAG, "Error closing stream - e=" + e.getMessage()); 
      } 
     } 
    } 
Powiązane problemy