2013-06-13 2 views
-1

문자열을 입력하고이를 Google 지오 코드로 보내고 JSON으로 다시 가져 오기 위해 경도와 위도를 가져 오려고합니다. 하지만이 코드를 실행할 때마다 나는 NetworkOnMainThreadException을 얻고 있습니다. 왜 그런가요? 이 문제를 어떻게 해결합니까?위도와 경도를 얻으면 NetworkOnMainThreadException이 발생합니다.

public class SearchAddressActivity extends Activity{ 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.search_on_address); 

     getLocationInfo("New Cross rd SE146AS London"); 
    } 


    public JSONObject getLocationInfo(String address) { 

     address = address.replaceAll(" ", "%20"); 
     Double lon = new Double(0); 
     Double lat = new Double(0); 
     HttpGet httpGet = new HttpGet("http://maps.google.com/maps/api/geocode/json?address="+ address + "&sensor=false"); 
     HttpClient client = new DefaultHttpClient(); 
     HttpResponse response; 
     StringBuilder stringBuilder = new StringBuilder(); 

     try { 
      response = client.execute(httpGet); 
      HttpEntity entity = response.getEntity(); 
      InputStream stream = entity.getContent(); 
      int b; 
      while ((b = stream.read()) != -1) { 
       stringBuilder.append((char) b); 
      } 
     } catch (ClientProtocolException e) { 
     } catch (IOException e) { 
     } 

     JSONObject jsonObject = new JSONObject(); 
     try { 
      jsonObject = new JSONObject(stringBuilder.toString()); 
     } catch (JSONException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

     try { 
      lon = ((JSONArray) jsonObject.get("results")).getJSONObject(0) 
        .getJSONObject("geometry").getJSONObject("location") 
        .getDouble("lng"); 

      lat = ((JSONArray) jsonObject.get("results")).getJSONObject(0) 
        .getJSONObject("geometry").getJSONObject("location") 
        .getDouble("lat"); 

     } catch (JSONException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

     Log.e("LON", String.valueOf(lon)); 
     Log.e("LAT", String.valueOf(lat)); 
     return jsonObject; 
    } 
} 

로그 캣

06-14 00:38:21.675: E/AndroidRuntime(18999): FATAL EXCEPTION: main 
06-14 00:38:21.675: E/AndroidRuntime(18999): java.lang.RuntimeException: Unable to start activity ComponentInfo{eu.mysite.www/eu.mysite.www.SearchAddressActivity}: android.os.NetworkOnMainThreadException 
06-14 00:38:21.675: E/AndroidRuntime(18999): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2100) 
06-14 00:38:21.675: E/AndroidRuntime(18999): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2125) 
06-14 00:38:21.675: E/AndroidRuntime(18999): at android.app.ActivityThread.access$600(ActivityThread.java:140) 
06-14 00:38:21.675: E/AndroidRuntime(18999): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1227) 
06-14 00:38:21.675: E/AndroidRuntime(18999): at android.os.Handler.dispatchMessage(Handler.java:99) 
06-14 00:38:21.675: E/AndroidRuntime(18999): at android.os.Looper.loop(Looper.java:137) 
06-14 00:38:21.675: E/AndroidRuntime(18999): at android.app.ActivityThread.main(ActivityThread.java:4898) 
06-14 00:38:21.675: E/AndroidRuntime(18999): at java.lang.reflect.Method.invokeNative(Native Method) 
06-14 00:38:21.675: E/AndroidRuntime(18999): at java.lang.reflect.Method.invoke(Method.java:511) 
06-14 00:38:21.675: E/AndroidRuntime(18999): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1006) 
06-14 00:38:21.675: E/AndroidRuntime(18999): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:773) 
06-14 00:38:21.675: E/AndroidRuntime(18999): at dalvik.system.NativeStart.main(Native Method) 
06-14 00:38:21.675: E/AndroidRuntime(18999): Caused by: android.os.NetworkOnMainThreadException 
06-14 00:38:21.675: E/AndroidRuntime(18999): at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1118) 
06-14 00:38:21.675: E/AndroidRuntime(18999): at java.net.InetAddress.lookupHostByName(InetAddress.java:385) 
06-14 00:38:21.675: E/AndroidRuntime(18999): at java.net.InetAddress.getAllByNameImpl(InetAddress.java:236) 
06-14 00:38:21.675: E/AndroidRuntime(18999): at java.net.InetAddress.getAllByName(InetAddress.java:214) 
06-14 00:38:21.675: E/AndroidRuntime(18999): at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:137) 
06-14 00:38:21.675: E/AndroidRuntime(18999): at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164) 
06-14 00:38:21.675: E/AndroidRuntime(18999): at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119) 
06-14 00:38:21.675: E/AndroidRuntime(18999): at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360) 
06-14 00:38:21.675: E/AndroidRuntime(18999): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:670) 
06-14 00:38:21.675: E/AndroidRuntime(18999): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:509) 
06-14 00:38:21.675: E/AndroidRuntime(18999): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487) 
06-14 00:38:21.675: E/AndroidRuntime(18999): at eu.mysite.www.SearchAddressActivity.getLocationInfo(SearchAddressActivity.java:47) 
06-14 00:38:21.675: E/AndroidRuntime(18999): at eu.mysite.www.SearchAddressActivity.onCreate(SearchAddressActivity.java:32) 
06-14 00:38:21.675: E/AndroidRuntime(18999): at android.app.Activity.performCreate(Activity.java:5206) 
06-14 00:38:21.675: E/AndroidRuntime(18999): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1083) 
06-14 00:38:21.675: E/AndroidRuntime(18999): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2064) 
06-14 00:38:21.675: E/AndroidRuntime(18999): ... 11 more 

답변

2

을 -

또한 제대로 검색어를 urlencode 촉구 주 스레드.
는 프로세스와 스레드 어떻게 그들에게
를 사용하는 방법과 다른 스레드에 올바르게 네트워크를 사용하는 방법에 대한 this 페이지에 대한 this 페이지를 읽어

예 : (Android Developers에서)

// Uses AsyncTask to create a task away from the main UI thread. This task takes a 
// URL string and uses it to create an HttpUrlConnection. Once the connection 
// has been established, the AsyncTask downloads the contents of the webpage as 
// an InputStream. Finally, the InputStream is converted into a string, which is 
// displayed in the UI by the AsyncTask's onPostExecute method. 
private class DownloadWebpageTask extends AsyncTask<String, Void, String> { 
    @Override 
    protected String doInBackground(String... urls) { 

     // params comes from the execute() call: params[0] is the url. 
     try { 
      return downloadUrl(urls[0]); 
     } catch (IOException e) { 
      return "Unable to retrieve web page. URL may be invalid."; 
     } 
    } 
    // onPostExecute displays the results of the AsyncTask. 
    @Override 
    protected void onPostExecute(String result) { 
     textView.setText(result); 
    } 
} 
1

오류 로그에서 중요한 라인은 다음과 같습니다

android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1118) 

그것은 "뭔가"이 요청을 차단하고 있다고 말한다 - 특히, 운영 체제를 (브라이언 로치 (Brian Roach)에게 그 사실을 분명히 해준 것에 대해 감사드립니다.) 네트워크 요청을 UI 스레드와 다른 스레드에 명시 적으로 지정해야합니다. 그렇지 않으면 네트워크가 응답 할 때까지 UI가 중단됩니다.

요청을 올바르게 작성하는 방법의 예는 Victor Lap의 대답을 참조하십시오. 오류가 당신은에 네트워크 작업을 수행 should'nt, 모든 것을 말해 ... 문제를 일으킬 수있는 유일한 문자가 아닌 "공간"

+2

그래, 그 "무언가"는 * 안드로이드 *입니다. 예외는 문제가 무엇인지 정확하게 말합니다 (URL을 무시하면 도움이되지 않습니다). 그들은 초보자들이 네트워크 통화로 UI 스레드를 묶어 두지 못하게했습니다. –

+1

@BrianRoach - 귀하의 의견에 감사드립니다. 지금 내 대답을 향상 ... – Floris

+0

(나는 downvoter 아니, BTW, 또는 내가 그것을 취소했을) –

관련 문제