[Update] Added repository link to download the project
I'm having this activity which connects to a URL to fetch data and display it using RecyclerView with a custom adapter. How can I edit this code to use AsyncTaskLoader instead of AsyncTask? here's the repository to download the very simple project 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();
}
}
}
I have tested multiple examples but they have different codes and triggers multiple errors with my code like this one and still looking for a solution which makes my code works fine.
Set adpter in your recyclerview and then call the loader like this way:
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>());
}
Performs actual task in background and returns the result.
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;
}
}
Add a method in your adapter like this:
public void setData(List<Event> data) {
this.data=data;
notifyDataSetChanged();
}