我无法从 AsyncTask 子类中的 doInBackground 方法获取数据

I can't fetch data from the doInBackground method in AsyncTask Subclass

我试图在我的应用程序中获取地震数据,但我的应用程序停止运行了。我的代码没有错误。甚至我添加了互联网许可。但是在获取数据时我认为会发生此错误。调试了没发现问题

Logcat:

2021-03-27 15:23:32.118 9533-9560/com.example.quakereportapp E/eglCodecCommon: glUtilsParamSize: unknow param 0x000082da 2021-03-27 15:23:32.118 9533-9560/com.example.quakereportapp E/eglCodecCommon: glUtilsParamSize: unknow param 0x000082da ioctl_ping failed for device_type=5, ret=-1 2021-03-27 15:23:37.091 9533-9533/com.example.quakereportapp E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.quakereportapp, PID: 9533 android.os.NetworkOnMainThreadException at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1513) at com.android.org.conscrypt.Platform.blockGuardOnNetwork(Platform.java:415) at com.android.org.conscrypt.ConscryptFileDescriptorSocket.shutdownAndFreeSslNative(ConscryptFileDescriptorSocket.java:1005) at com.android.org.conscrypt.ConscryptFileDescriptorSocket.close(ConscryptFileDescriptorSocket.java:1000) at com.android.okhttp.internal.Util.closeQuietly(Util.java:86) at com.android.okhttp.internal.http.StreamAllocation.deallocate(StreamAllocation.java:256) at com.android.okhttp.internal.http.StreamAllocation.connectionFailed(StreamAllocation.java:293) at com.android.okhttp.internal.http.HttpEngine.close(HttpEngine.java:445) at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:509) at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:407) at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:538) at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.getResponseCode(DelegatingHttpsURLConnection.java:105) at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:26) at com.example.quakereportapp.QueryUtils.makeHttpRequest(QueryUtils.java:82) at com.example.quakereportapp.QueryUtils.fetchEarthquakeData(QueryUtils.java:35) at com.example.quakereportapp.MainActivity.updateUi(MainActivity.java:27) at com.example.quakereportapp.MainActivity.access0(MainActivity.java:14) at com.example.quakereportapp.MainActivity$EarthQuakeAsyncTask.onPostExecute(MainActivity.java:58) at com.example.quakereportapp.MainActivity$EarthQuakeAsyncTask.onPostExecute(MainActivity.java:33) at android.os.AsyncTask.finish(AsyncTask.java:695) at android.os.AsyncTask.access0(AsyncTask.java:180) at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:712) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:193) at android.app.ActivityThread.main(ActivityThread.java:6669) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)

我的 AsyncTask 子Class

private void updateUi(List<Earthquake> earthquakes) {
    listView = findViewById(R.id.list_view);
    ArrayList<Earthquake> earthquake = QueryUtils.fetchEarthquakeData(url);
    EarthquakeAdapter earthquakeAdapterArrayAdapter = new EarthquakeAdapter(this, earthquake);
    listView.setAdapter(earthquakeAdapterArrayAdapter);
}
private class EarthQuakeAsyncTask extends AsyncTask<String, Void, List<Earthquake>> {
 
    @Override
    protected  ArrayList<Earthquake> doInBackground(String... urls) {
        ArrayList<Earthquake> result = QueryUtils.fetchEarthquakeData(urls[0]);
        return result;
    }


    @Override
    protected void onPostExecute(List<Earthquake> result) {
        updateUi(result);
    }

我的 JSON 来自 QueryUtils 的提取器方法 Class

private static ArrayList<Earthquake> extractFeatureFromJson(String earthquakeJSON) {
    // If the JSON string is empty or null, then return early.
    if (TextUtils.isEmpty(earthquakeJSON)) {
        return null;
    }

    ArrayList<Earthquake> earthquakes = new ArrayList<>();


    try {
        JSONObject baseJsonResponse = new JSONObject(earthquakeJSON);
        JSONArray earthquakeArray = baseJsonResponse.getJSONArray("features");

        for (int i = 0; i < earthquakeArray.length(); i++) {
            //creates object from the given array
            JSONObject currentEarthquake = earthquakeArray.getJSONObject(i);
            //stores all the data from properties to properties object
            JSONObject properties = currentEarthquake.getJSONObject("properties");
            //here we assign the value of the specified keys from the properties
            String magnitude = properties.getString("mag");
            String location = properties.getString("place");
            long time = properties.getLong("time");
            //and now we create a new earthquake in every loop
            Earthquake earthquake = new Earthquake(magnitude, location, time);
            //finally we add it to the earthquakes list
            earthquakes.add(earthquake);
        }
    } catch (JSONException e) {
        Log.e(LOG_TAG, "Problem parsing the earthquake JSON results", e);
    }
    return earthquakes;
}

抛出异常是因为您从主线程调用 API。您的代码中的问题是您两次调用 API 。一次进入 doInBackground,然后再次进入 updateUi。 从 updateUi 中删除对 QueryUtils.fetchEarthquakeData(url) 的调用,它应该如下所示。

private void updateUi(List<Earthquake> earthquakes) {
    listView = findViewById(R.id.list_view);
    EarthquakeAdapter earthquakeAdapterArrayAdapter = new EarthquakeAdapter(this, earthquakes);
    listView.setAdapter(earthquakeAdapterArrayAdapter);
}