Android: 如何将 AsyncTaskLoader 添加到此 RecyclerView

Android: How to add AsyncTaskLoader to this RecyclerView

[更新] 添加存储库 link 以下载项目

我有这个 activity 连接到 URL 以获取数据并使用带有自定义适配器的 RecyclerView 显示它。如何编辑此代码以使用 AsyncTaskLoader 而不是 AsyncTask?这是下载非常简单的项目的存储库 Soonami tutorial app

public class MainActivity extends AppCompatActivity {

  private RecyclerView recyclerView;
  public static QuakesAdapter quakesAdapter;
  public static ArrayList<Event> eventsList = new ArrayList<>();
  public static final String USGS_REQUEST_URL =
        "https://earthquake.usgs.gov/fdsnws/event/1/query?format=geojson&starttime=2018-01-01&endtime=2018-12-01&minmagnitude=6&limit=50";

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    recyclerView = findViewById(R.id.recycler_view);
    quakesAdapter = new QuakesAdapter(this, eventsList);

    //defining recyclerView and setting the adapter

    quakesAdapter.notifyDataSetChanged();

    FetchData fetchData= new FetchData();
    fetchData.execute();
}


private class FetchData extends AsyncTask<String, Void, ArrayList<Event>> {

    String myDdata = "";
    String line = "";

    @Override
    protected ArrayList<Event> doInBackground(String... params) {

        try {

            //opening the connection

            if (httpURLConnection.getResponseCode() == 200) {
                InputStream inputStream = httpURLConnection.getInputStream();
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));

                while(line != null){
                    line = bufferedReader.readLine();
                    myDdata = myDdata + line;
                }

                JSONObject jsonObject = new JSONObject(myDdata);
                eventsList.clear();

                JSONArray jsonArray = jsonObject.getJSONArray("features");

                for(int i = 0; i < jsonArray.length(); i++){

                    //getting values of the 3 attributes

                    eventsList.add(new Event(title, time, tsunamiAlert));
                }

                if (inputStream != null) {
                    inputStream.close();
                }

            } else {
                Log.e("Connection Error: ", "Error response code: " + httpURLConnection.getResponseCode());
            }

            if (httpURLConnection != null) {
                httpURLConnection.disconnect();
            }

        }
        catch (MalformedURLException e) {
            e.printStackTrace();
        }

        catch (IOException e) {
            e.printStackTrace();
        } catch (JSONException e) {
            e.printStackTrace();
        }

        return null;
    }

    @Override
    protected void onPostExecute(ArrayList<Event> result) {
        super.onPostExecute(result);
        quakesAdapter.notifyDataSetChanged();
    }
  }
}

我已经测试了多个示例,但它们有不同的代码并触发了我的代码的多个错误,例如 this one,并且仍在寻找使我的代码正常工作的解决方案。

您遇到过哪种错误?

我建议为您的 AsynkTask 使用 Java 接口和 CallBack 方法,在这种情况下,每当您的 AsynkTask 任务完成时,它都会使用该回调方法通知 Activity,您可以执行 notifyDataSetChange 方法适配器。

在你的 recyclerview 中设置适配器,然后像这样调用加载程序:

public class MainActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<List<Event>> {
        {

            private RecyclerView recyclerView;
            public static QuakesAdapter quakesAdapter;
            public static ArrayList<Event> eventsList = new ArrayList<>();
            public static final String USGS_REQUEST_URL =
                    "https://earthquake.usgs.gov/fdsnws/event/1/query?format=geojson&starttime=2018-01-01&endtime=2018-12-01&minmagnitude=6&limit=50";

            @Override
            protected void onCreate (Bundle savedInstanceState){
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);

            recyclerView = findViewById(R.id.recycler_view);
            quakesAdapter = new QuakesAdapter(this, eventsList);

            //defining recyclerView and setting the adapter

            recyclerView.setAdapter(quakesAdapter);

            getSupportLoaderManager().initLoader(1, null, this).forceLoad();

        }

            @Override
            public Loader<List<Event>> onCreateLoader ( int id, Bundle args){
            return new FetchData(MainActivity.this);
        }
            @Override
            public void onLoadFinished (Loader < List < Event >> loader, List < Event > data){
            quakesAdapter.setData(data);
        }
            @Override
            public void onLoaderReset (Loader < List < Event >> loader) {
            quakesAdapter.setData(new ArrayList<Event>());

}

在后台执行实际任务并 returns 结果。

private static class FetchData extends AsyncTaskLoader<List<Event>>{

        String myDdata = "";
        String line = "";
           public FetchData(Context context) {
            super(context);
        }
        @Override
        public List<Event> loadInBackground () {

            try {
                List<Event> list = new ArrayList<Event>();

                //opening the connection

                if (httpURLConnection.getResponseCode() == 200) {
                    InputStream inputStream = httpURLConnection.getInputStream();
                    BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));

                    while (line != null) {
                        line = bufferedReader.readLine();
                        myDdata = myDdata + line;
                    }

                    JSONObject jsonObject = new JSONObject(myDdata);

                    JSONArray jsonArray = jsonObject.getJSONArray("features");

                    for (int i = 0; i < jsonArray.length(); i++) {

                        //getting values of the 3 attributes

                        eventsList.add(new Event(title, time, tsunamiAlert));
                    }

                    if (inputStream != null) {
                        inputStream.close();
                    }

                } else {
                    Log.e("Connection Error: ", "Error response code: " + httpURLConnection.getResponseCode());
                }

                if (httpURLConnection != null) {
                    httpURLConnection.disconnect();
                }

            } catch (MalformedURLException e) {
                e.printStackTrace();
            }

            return eventsList;
        }
    }

像这样在你的适配器中添加一个方法:

public void setData(List<Event> data) {
        this.data=data;
        notifyDataSetChanged();
    }