2013-05-08 19 views
20

Tutaj używam tego kodu obciążenia Json. Jest to praca dobrze z Android 2.2, ale gdy używam android 4.2 rzuca android.os.NetworkOnMainThreadException wyjątek proszę dać mi roztworowiandroid.os.NetworkOnMainThreadException z Androidem 4.2

public class JSONParser { 

    static InputStream is = null; 

static JSONObject jObj = null; 
static String json = ""; 

// constructor 
public JSONParser() { 

} 

public JSONObject getJSONFromUrl(String url) { 

    // Making HTTP request 
    try { 
     // defaultHttpClient 
     DefaultHttpClient httpClient = new DefaultHttpClient(); 
     HttpGet httpPost = new HttpGet(url); 

      HttpResponse getResponse = httpClient.execute(httpPost); 
      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(); 

     //HttpResponse httpResponse = httpClient.execute(httpPost); 
     //HttpEntity httpEntity = httpResponse.getEntity(); 
     is = getResponseEntity.getContent();    

    } catch (UnsupportedEncodingException e) { 
     e.printStackTrace(); 
    } catch (ClientProtocolException e) { 
     e.printStackTrace(); 
    } catch (IOException e) { 
     Log.d("IO", e.getMessage().toString()); 
     e.printStackTrace(); 

    } 

    try { 
     BufferedReader reader = new BufferedReader(new InputStreamReader(
       is, "iso-8859-1"), 8); 
     StringBuilder sb = new StringBuilder(); 
     String line = null; 
     while ((line = reader.readLine()) != null) { 
      sb.append(line + "\n"); 
     } 
     is.close(); 
     json = sb.toString(); 
    } catch (Exception e) { 
     Log.e("Buffer Error", "Error converting result " + e.toString()); 
    } 

    // try parse the string to a JSON object 
    try { 
     jObj = new JSONObject(json); 
    } catch (JSONException e) { 
     Log.e("JSON Parser", "Error parsing data " + e.toString()); 
    } 

    // return JSON String 
    return jObj; 

} 

}

Jestem również za pomocą interfejsu API Google.

+0

Pytanie ma zostały tu odebrane: http://stackoverflow.com/questions/5150637/networkonmainthreade xception –

+0

http://stackoverflow.com/a/12615724/1168654 –

Odpowiedz

73

Napisz poniższy kod do pliku MainActivity po ustawieniu setContentView (R.layout.activity_main);

if (android.os.Build.VERSION.SDK_INT > 9) { 
    StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build(); 
    StrictMode.setThreadPolicy(policy); 
} 

Poniżej instrukcji importu do pliku Java.

import android.os.StrictMode; 
+38

, nie jest prawidłowym sposobem wyłączenia StrictMode. Prawidłowy sposób polega na wywoływaniu operacji sieciowych w AsyncTask zamiast wyłączaniu –

+0

. @SankarV mówi, że powinno się to odbywać przy użyciu AsyncTask zamiast wyłączania trybu strictmode. –

+0

Nie jest to zalecane. AsyncTask to lepszy sposób na zrobienie tego. –

6

proszę upewnić się, że nie robią żadnego dostępu do sieci na UI wątek, zamiast zrobić to w Async Task

Powodem, dlaczego awarii aplikacji na Androidzie 3.0 i nowszych wersjach, ale działa na Android 2.x ponieważ od czasu HoneyComb są znacznie ostrzejsze w kwestii nadużywania wobec wątku UI. Na przykład, gdy urządzenie z Androidem, na którym działa HoneyComb lub wyższa, wykrywa dostęp do sieci w wątku UI, zostanie zgłoszony wyjątek NetworkOnMainThreadException.

Zobacz this

+0

zamiast HoneyComb i Ice Cream Sandwich powiem od HoneyComb. W rzeczywistości JB ma tę samą politykę, – Blackbelt

1

android.os.NetworkOnMainThreadException występuje podczas próby uzyskania dostępu do sieci na głównym wątku (możliwość wykonania główny aktywność). Aby tego uniknąć, należy utworzyć oddzielny wątek lub implementację AsyncTask lub Runnable, aby wykonać ładowanie danych JSON. Od HoneyComb nie można dalej wykonywać zadania sieciowego w głównym wątku. Here jest implementacją używającą AsyncTask do wykonania zadania sieciowego

1

Zastosowanie StrictMode coś takiego: -

if (android.os.Build.VERSION.SDK_INT > 9) { 
     StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build(); 

     StrictMode.setThreadPolicy(policy); 
     } 
+2

to nie jest poprawny sposób, aby wyłączyć StrictMode. Poprawnym sposobem jest wywołanie operacji sieciowych w AsyncTask zamiast wyłączania. czy dostarczyli czek tylko na wyłączenie? –

+0

możemy użyć asynkTask również, ale dla mnie działa –

+0

ya będzie działać, ale nie jest najlepszy sposób. dostarczyli czek, aby deweloper wywoływał operacje sieciowe w osobnym wątku, a nie po prostu się wyłączał. –

13

Jest to poprawny sposób:

public class JSONParser extends AsyncTask <String, Void, String>{ 

    static InputStream is = null; 

static JSONObject jObj = null; 
static String json = ""; 

// constructor 
public JSONParser() { 

} 
@Override 
protected String doInBackground(String... params) { 


    // Making HTTP request 
    try { 
     // defaultHttpClient 
     DefaultHttpClient httpClient = new DefaultHttpClient(); 
     HttpGet httpPost = new HttpGet(url); 

      HttpResponse getResponse = httpClient.execute(httpPost); 
      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(); 

     //HttpResponse httpResponse = httpClient.execute(httpPost); 
     //HttpEntity httpEntity = httpResponse.getEntity(); 
     is = getResponseEntity.getContent();    

    } catch (UnsupportedEncodingException e) { 
     e.printStackTrace(); 
    } catch (ClientProtocolException e) { 
     e.printStackTrace(); 
    } catch (IOException e) { 
     Log.d("IO", e.getMessage().toString()); 
     e.printStackTrace(); 

    } 

    try { 
     BufferedReader reader = new BufferedReader(new InputStreamReader(
       is, "iso-8859-1"), 8); 
     StringBuilder sb = new StringBuilder(); 
     String line = null; 
     while ((line = reader.readLine()) != null) { 
      sb.append(line + "\n"); 
     } 
     is.close(); 
     json = sb.toString(); 
    } catch (Exception e) { 
     Log.e("Buffer Error", "Error converting result " + e.toString()); 
    } 

    // try parse the string to a JSON object 
    try { 
     jObj = new JSONObject(json); 
    } catch (JSONException e) { 
     Log.e("JSON Parser", "Error parsing data " + e.toString()); 
    } 

    // return JSON String 
    return jObj; 


} 
protected void onPostExecute(String page) 
{ 
    //onPostExecute 
} 
} 

nazwać (od główny):

mJSONParser = new JSONParser(); 
mJSONParser.execute(); 
+0

czy nawet to przetestowałeś? Nie działa, jaki jest ten adres URL? return obj nie jest dostępny poza pętlą –