2016-09-27 18 views
0

我從Fragment調用一個名爲MapsActivity的Activity。當在ANDROID中的背景上運行時獲取java.lang.RunTimeException

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
         Bundle savedInstanceState) { 


    // Inflate the layout for this fragment 

    rootView = inflater.inflate(R.layout.fragment_one, container, false); 
    ibTrackEmp = (ImageView)rootView.findViewById(R.id.ibTrackEmp); 
    ibTrackEmp.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      Intent intent = new Intent(getActivity(), MapsActivity.class); 
      startActivity(intent); 
     } 
    }); 
    return rootView; 
} 

現在,在MapsActivity.java,我調用Web服務作爲後臺任務

private class GetALLGPSTask extends AsyncTask<String, Void, String> { 
    private TextView textView; 

    public GetALLGPSTask() { 

    } 

    @Override 
    protected String doInBackground(String... strings) { 
     String result = "Unable to fetch from SAP"; 
     try { 
      URL url = new URL(strings[0]); 
      final String basicAuth = "Basic " + Base64.encodeToString("xxxx:[email protected]".getBytes(), Base64.NO_WRAP); 
      HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); 

      urlConnection.setReadTimeout(90000); 
      urlConnection.setConnectTimeout(55000); 
      urlConnection.setRequestMethod("GET"); 
      urlConnection.setDoOutput(true); 
      urlConnection.setRequestProperty ("Authorization", basicAuth); 


      InputStream stream = new BufferedInputStream(urlConnection.getInputStream()); 
      BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(stream)); 
      StringBuilder builder = new StringBuilder(); 

      String inputString; 
      while ((inputString = bufferedReader.readLine()) != null) { 
       builder.append(inputString); 
      } 

      int responsecode = urlConnection.getResponseCode(); 
      Log.d("ResponseCode", String.valueOf(responsecode)); 
      if(responsecode == 200){ 
       result = "GPS Coordinates Updated Successfully"; 

       try { 
        JSONArray jsonArray = new JSONArray(builder.toString()); 
        List<Pair<String, String>> allNames = new ArrayList<>(); 
        final int numberOfItemsInResp = jsonArray.length(); 
        for (int i = 0; i < numberOfItemsInResp; i++) { 
         JSONObject jobj = jsonArray.getJSONObject(i); 
         String name = jobj.getString("NAME"); 
         String addlatitude = jobj.getString("LATITUDE"); 
         String addlongitude = jobj.getString("LONGITUDE"); 

         LatLng newemp = new LatLng(Double.valueOf(addlatitude), Double.valueOf(addlongitude)); 
         mMap.addMarker(new MarkerOptions().position(newemp).title("UserName: "+name)); 
        } 
       } catch (JSONException e) { 
        Log.e("JSON Parser", "Error parsing data " + e.toString()); 
       } 

      } 
      urlConnection.disconnect(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     return result; 
    } 

    @Override 
    protected void onPostExecute(String temp) { 

     Toast.makeText(MapsActivity.this, 
       temp, Toast.LENGTH_SHORT).show(); 
    } 

這裏,Web服務獲取調用,但應用程序初始化爲第一個屏幕。 我得到以下錯誤日誌

                   --------- beginning of crash 
09-27 15:52:31.912 31508-31767/com.example.sd0003.appslider E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #2 
                      Process: com.example.sd0003.appslider, PID: 31508 
                      java.lang.RuntimeException: An error occurred while executing doInBackground() 
                       at android.os.AsyncTask$3.done(AsyncTask.java:309) 
                       at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354) 
                       at java.util.concurrent.FutureTask.setException(FutureTask.java:223) 
                       at java.util.concurrent.FutureTask.run(FutureTask.java:242) 
                       at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234) 
                       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113) 
                       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588) 
                       at java.lang.Thread.run(Thread.java:818) 
                      Caused by: java.lang.IllegalStateException: Not on the main thread 
                       at maps.w.d.a(Unknown Source) 
                       at maps.y.F.a(Unknown Source) 
                       at maps.ad.t.a(Unknown Source) 
                       at ua.onTransact(:com.google.android.gms.DynamiteModulesB:167) 
                       at android.os.Binder.transact(Binder.java:392) 
                       at com.google.android.gms.maps.internal.IGoogleMapDelegate$zza$zza.addMarker(Unknown Source) 
                       at com.google.android.gms.maps.GoogleMap.addMarker(Unknown Source) 
                       at com.example.sd0003.appslider.MapsActivity$GetALLGPSTask.doInBackground(MapsActivity.java:152) 
                       at com.example.sd0003.appslider.MapsActivity$GetALLGPSTask.doInBackground(MapsActivity.java:105) 
                       at android.os.AsyncTask$2.call(AsyncTask.java:295) 
                       at java.util.concurrent.FutureTask.run(FutureTask.java:237) 
                       at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)  
                       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)  
                       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)  
                       at java.lang.Thread.run(Thread.java:818)  
09-27 15:52:31.912 31508-31767/com.example.sd0003.appslider E/AbstractTracker: Can't create handler inside thread that has not called Looper.prepare() 
09-27 15:52:31.913 31508-31767/com.example.sd0003.appslider D/AppTracker: App Event: crash 
09-27 15:52:31.916 31508-31767/com.example.sd0003.appslider E/AbstractTracker: mTrackerAsyncQueryHandler is null 
09-27 15:52:31.942 31508-31767/com.example.sd0003.appslider I/Process: Sending signal. PID: 31508 SIG: 9 
+3

我認爲堆棧跟蹤非常清晰。你必須在主線程上調用'mMap.addMarker()'。 –

回答

1

您不應該從後臺線程執行UI更新。在這種情況下,您不應該將標記添加到mMap參考中。

相反,您應該返回位置名稱和緯度/經度對的列表,並處理onPostExecute中主線程的UI更新。考慮返回類似List<Pair<String, LatLng>> locations之類的數據集。然後

你的實現應該是這樣的:

private class GetALLGPSTask extends AsyncTask<String, Void, List<Pair<String, LatLng>>> { 
    private TextView textView; 

    public GetALLGPSTask() { 

    } 

    @Override 
    protected List<Pair<String, LatLng>> doInBackground(String... strings) { 
     List<Pair<String, LatLng>> allLocations = new ArrayList<>(); 
     try { 
      URL url = new URL(strings[0]); 
      final String basicAuth = "Basic " + Base64.encodeToString("xxxx:[email protected]".getBytes(), Base64.NO_WRAP); 
      HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); 

      urlConnection.setReadTimeout(90000); 
      urlConnection.setConnectTimeout(55000); 
      urlConnection.setRequestMethod("GET"); 
      urlConnection.setDoOutput(true); 
      urlConnection.setRequestProperty ("Authorization", basicAuth); 


      InputStream stream = new BufferedInputStream(urlConnection.getInputStream()); 
      BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(stream)); 
      StringBuilder builder = new StringBuilder(); 

      String inputString; 
      while ((inputString = bufferedReader.readLine()) != null) { 
       builder.append(inputString); 
      } 

      int responsecode = urlConnection.getResponseCode(); 
      Log.d("ResponseCode", String.valueOf(responsecode)); 
      if(responsecode == 200){ 

       try { 
        JSONArray jsonArray = new JSONArray(builder.toString()); 
        final int numberOfItemsInResp = jsonArray.length(); 
        for (int i = 0; i < numberOfItemsInResp; i++) { 
         JSONObject jobj = jsonArray.getJSONObject(i); 
         String name = jobj.getString("NAME"); 
         String latitude = jobj.getString("LATITUDE"); 
         String longitude = jobj.getString("LONGITUDE"); 

         LatLng latLng = new LatLng(Double.valueOf(addlatitude), Double.valueOf(addlongitude)); 
         allLocations.add(new Pair<>(name, latLng)) 
        } 
       } catch (JSONException e) { 
        Log.e("JSON Parser", "Error parsing data " + e.toString()); 
       } 

      } 
      urlConnection.disconnect(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     return allLocations; 
    } 

    @Override 
    protected void onPostExecute(List<Pair<String, LatLng>> locations) { 
     for (Pair<String, LatLng> location : locations) { 
      mMap.addMarker(new MarkerOptions().position(location.second).title("UserName: " + location.first)); 
     } 
    } 
} 

邊注:從來沒有使用你的allNames列表。

+0

完美答案!!!!謝謝!!! –