在ANDROID

时间:2016-09-27 20:00:07

标签: java android android-asynctask

我正在从Fragment调用一个名为MapsActivity的Activity。

@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服务称为BackGround任务

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:xxxx@1223".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

1 个答案:

答案 0 :(得分: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:xxxx@1223".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列表从未使用过。