java - 在 ANDROID 中后台运行时出现 java.lang.RunTimeException

标签 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 服务调用为后台任务

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

最佳答案

您不应该从后台线程执行 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列表从未使用过。

关于java - 在 ANDROID 中后台运行时出现 java.lang.RunTimeException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39733309/

相关文章:

java - 是否有类似于 Java 的 lxml 或 nokogiri 的库?

java - 为什么Spring任务调度程序不同时执行任务?

java - Android:在RecyclerView中显示AsyncTask的数据

android - AsyncTask 完成执行后 ExpandableListView 未更新

带有来自 Web 服务的数据的 Android AutoCompleteTextView,显示建议列表时出现问题

java - HashMap(它)会做什么?

java - Maven 在 "mvn site"期间抛出错误,但在 "mvn compile"/"mvn test"下工作正常

android - WooCommerce API : create order and checkout

java - AlertDialog 中的文本颜色未更改

java - Wifi 扫描结果给我奇怪的结果