Android: как добавить AsyncTaskLoader в этот RecyclerView - PullRequest
1 голос
/ 24 апреля 2019

[Update] Добавлена ​​ссылка на репозиторий для загрузки проекта

У меня есть это действие, которое подключается к URL-адресу для получения данных и отображения их с помощью RecyclerView с пользовательским адаптером. Как я могу отредактировать этот код, чтобы использовать AsyncTaskLoader вместо AsyncTask? Вот репозиторий для загрузки очень простого проекта Приложение для Soonami

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();
    }
  }
}

Я протестировал несколько примеров, но они имеют разные коды и вызывают несколько ошибок с моим кодом, таким как этот , и все еще ищу решение, которое делает мой код хорошо работающим.

Ответы [ 2 ]

2 голосов
/ 24 апреля 2019

Установите adpter в вашем обзоре переработчика и затем вызывайте загрузчик следующим образом:

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>());

}

Выполняет актуальную задачу в фоновом режиме и возвращает результат.

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();
    }
0 голосов
/ 24 апреля 2019

С какой ошибкой вы сталкиваетесь?

Я предлагаю использовать интерфейс Java и метод CallBack для вашего AsynkTask, в этом случае, когда ваша задача AsynkTask выполнена, она уведомляет об этом Activity с помощью этого метода обратного вызова, и вы можете выполнить метод notifyDataSetChange адаптера.

...