2012-11-14 5 views
0

Google지도 뷰를 사용하는 앱이 있습니다. 이 코드는 내 옛날 장치 안드로이드 2.1에서 잘 작동하지만 내 htc 1 x 실행중인 안드로이드 4 나는 메인 스레드 예외에서 네트워크 피하기 위해 비동기했다.안드로이드 앱에지도가 표시되지 않습니다.

지도보기에 약 1 초가 지나면 충돌이 발생합니다. 오류에 Looper.prepare()를 호출하지 않는 스레드를 나타내는 예외가 있습니다. 어떤 아이디어를 어떻게 해결할 수 있는지 감사합니다.

다음은 예외이며 아래에 소스를 게시합니다.

11-14 13:29:31.025: W/dalvikvm(20404): threadid=15: thread exiting with uncaught exception (group=0x40a7d228) 
11-14 13:29:31.025: E/AndroidRuntime(20404): FATAL EXCEPTION: AsyncTask #4 
11-14 13:29:31.025: E/AndroidRuntime(20404): java.lang.RuntimeException: An error occured while executing doInBackground() 
11-14 13:29:31.025: E/AndroidRuntime(20404): at android.os.AsyncTask$3.done(AsyncTask.java:278) 
11-14 13:29:31.025: E/AndroidRuntime(20404): at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273) 
11-14 13:29:31.025: E/AndroidRuntime(20404): at java.util.concurrent.FutureTask.setException(FutureTask.java:124) 
11-14 13:29:31.025: E/AndroidRuntime(20404): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307) 
11-14 13:29:31.025: E/AndroidRuntime(20404): at java.util.concurrent.FutureTask.run(FutureTask.java:137) 
11-14 13:29:31.025: E/AndroidRuntime(20404): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076) 
11-14 13:29:31.025: E/AndroidRuntime(20404): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569) 
11-14 13:29:31.025: E/AndroidRuntime(20404): at java.lang.Thread.run(Thread.java:864) 
11-14 13:29:31.025: E/AndroidRuntime(20404): Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare() 
11-14 13:29:31.025: E/AndroidRuntime(20404): at android.os.Handler.<init>(Handler.java:121) 
11-14 13:29:31.025: E/AndroidRuntime(20404): at android.widget.ZoomButtonsController$2.<init>(ZoomButtonsController.java:170) 
11-14 13:29:31.025: E/AndroidRuntime(20404): at android.widget.ZoomButtonsController.<init>(ZoomButtonsController.java:170) 
11-14 13:29:31.025: E/AndroidRuntime(20404): at com.google.android.maps.MapView.createZoomButtonsController(MapView.java:1444) 
11-14 13:29:31.025: E/AndroidRuntime(20404): at com.google.android.maps.MapView.setBuiltInZoomControls(MapView.java:1498) 
11-14 13:29:31.025: E/AndroidRuntime(20404): at com.carefreegroup.GetClientDirections.getRoute(GetClientDirections.java:173) 
11-14 13:29:31.025: E/AndroidRuntime(20404): at com.carefreegroup.GetClientDirections$AsyncGetRoute.doInBackground(GetClientDirections.java:87) 
11-14 13:29:31.025: E/AndroidRuntime(20404): at com.carefreegroup.GetClientDirections$AsyncGetRoute.doInBackground(GetClientDirections.java:1) 
11-14 13:29:31.025: E/AndroidRuntime(20404): at android.os.AsyncTask$2.call(AsyncTask.java:264) 
11-14 13:29:31.025: E/AndroidRuntime(20404): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305) 

.

public class GetClientDirections extends MapActivity { 

    private MapController mapController; 
    private MapView mapView; 

    private List<Overlay> mapOverlays; 
    private StringBuffer response = null; 
    private static final String TAG = GetClientDirections.class.getSimpleName(); 
    private double lon; 
    private double lat; 
    private JSONArray routes = null; 
    private JSONObject bounds = null; 
    private JSONObject northeast = null; 
    private JSONObject anonObject; 
    private JSONObject overViewPolyline; 
    private String stringUrl; 
    private String polyPoints; 
    Context context; 
    private String endAddr; 
    private String startAddr; 

    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.mapview); 

     context = this; 
     startAddr = "wf120lj"; 
     endAddr = "wf27ar"; 



       StringBuilder sb = new StringBuilder(); 
       sb.append("http://maps.google.com/maps/api/directions/json?origin="); 
       sb.append(startAddr); 
       sb.append("&destination="); 
       sb.append(endAddr); 
       sb.append("&sensor=false"); 

       stringUrl = sb.toString(); 
       Log.e(TAG, "url = " + stringUrl); 


       AsyncGetRoute agr = new AsyncGetRoute(); 
       agr.execute(); 




    }// end of onCreate 


    private class AsyncGetRoute extends AsyncTask<Void, Void, Void> { 



     @Override 
     protected Void doInBackground(Void... params) { 

      getRoute(); 
      return null; 
     } 


    } 





    public void getRoute() { 

     response = new StringBuffer(); 
     URL url = null; 
     try { 
      url = new URL(stringUrl); 
     } catch (MalformedURLException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     HttpURLConnection httpconn = null; 
     try { 
      httpconn = (HttpURLConnection) url.openConnection(); 
     } catch (IOException e1) { 
      // TODO Auto-generated catch block 
      e1.printStackTrace(); 
     } 
     try { 
      if (httpconn.getResponseCode() == HttpURLConnection.HTTP_OK) { 
       // Log.e(TAG,"response code OK "); 
       BufferedReader input = new BufferedReader(
         new InputStreamReader(httpconn.getInputStream()), 8192); 
       String strLine = null; 

       while ((strLine = input.readLine()) != null) { 
        // Log.e(TAG,""+strLine); 
        response.append(strLine); 
       } 
       input.close(); 
      } 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

     String jsonOutput = response.toString(); 
     Log.e(TAG, "jsonOutput = " + jsonOutput); 

     JSONObject results = null; 
     try { 

      results = new JSONObject(jsonOutput); 

      routes = results.getJSONArray("routes"); 

      anonObject = routes.getJSONObject(0); 
      bounds = anonObject.getJSONObject("bounds"); 
      overViewPolyline = anonObject.getJSONObject("overview_polyline"); 
      polyPoints = overViewPolyline.getString("points"); 
      Log.e(TAG, "overview_polyline = " + overViewPolyline); 
      Log.e(TAG, "points = " + polyPoints); 

      northeast = bounds.getJSONObject("northeast"); 

      lat = (Double) northeast.get("lat"); 

      lon = (Double) northeast.get("lng"); 

      Log.e(TAG, "lon/lat = " + lon + " " + lat); 

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



     List<GeoPoint> list = decodePoly(polyPoints); 



     mapView = (MapView) findViewById(R.id.cfmapview); 
     mapView.setBuiltInZoomControls(true); 
     mapView.setEnabled(true); 
     mapView.setSatellite(true); 
     mapController = mapView.getController(); 
     mapController.setZoom(10); 

     mapOverlays = mapView.getOverlays(); 

     mapOverlays.add(new RoutePathOverlay(list, getApplicationContext())); 
     mapController.animateTo(new GeoPoint(list.get(0).getLatitudeE6(), list 
       .get(0).getLongitudeE6())); 

     mapView.invalidate(); 

    }// end of getRoute 




    private List<GeoPoint> decodePoly(String encoded) { 

     List<GeoPoint> poly = new ArrayList<GeoPoint>(); 
     int index = 0, len = encoded.length(); 
     int lat = 0, lng = 0; 

     while (index < len) { 
      int b, shift = 0, result = 0; 
      do { 
       b = encoded.charAt(index++) - 63; 
       result |= (b & 0x1f) << shift; 
       shift += 5; 
      } while (b >= 0x20); 
      int dlat = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1)); 
      lat += dlat; 

      shift = 0; 
      result = 0; 
      do { 
       b = encoded.charAt(index++) - 63; 
       result |= (b & 0x1f) << shift; 
       shift += 5; 
      } while (b >= 0x20); 
      int dlng = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1)); 
      lng += dlng; 

      GeoPoint p = new GeoPoint((int) (((double) lat/1E5) * 1E6), 
        (int) (((double) lng/1E5) * 1E6)); 
      poly.add(p); 
     } 

     return poly; 
    } 

    @Override 
    protected boolean isRouteDisplayed() { 
     // TODO Auto-generated method stub 
     return false; 
    } 
} 

답변

2

doInBackground()에서보기를 업데이트하면 안되며 onPostExecute()을 덮어 쓰고 거기에서 MapView를 업데이트해야합니다. getRoute() 메서드를 두 개로 나눕니다.

+0

대단히 감사합니다. 멍청한 실수! – turtleboy

+0

4가 아니라 2.1이 아니기 시작한 것은 흥미 롭습니다. 구현을 변경해야한다고 생각합니다. – dmon

+0

2.1에서 작동 할 때 UI에서 네트워크 작업을 수행하는 것이 좋다고 생각하여 비동기가 없었습니다. 4에서 당신은 비동기가 필요합니다. 그래서 내가 왜 오류를 가지는지, 나는 비동기를 올바르게 구현하지 못했습니다. – turtleboy

0

비 -ui 스레드에서 getRoute() 메소드를 사용합니다. MapView는 UI 스레드에서 업데이트해야합니다.

관련 문제