Skip to content

Instantly share code, notes, and snippets.

@udacityandroid
Created July 7, 2016 21:03
Show Gist options
  • Save udacityandroid/ee8fe10c04ec2d912c509ee3fb287149 to your computer and use it in GitHub Desktop.
Save udacityandroid/ee8fe10c04ec2d912c509ee3fb287149 to your computer and use it in GitHub Desktop.
Switch from AsyncTask to AsyncTaskLoader
public class EarthquakeActivity extends AppCompatActivity
implements LoaderCallbacks<List<Earthquake>> {
...
@Override
public Loader<List<Earthquake>> onCreateLoader(int i, Bundle bundle) {
// TODO: Create a new loader for the given URL
}
@Override
public void onLoadFinished(Loader<List<Earthquake>> loader, List<Earthquake> earthquakes) {
// TODO: Update the UI with the result
}
@Override
public void onLoaderReset(Loader<List<Earthquake>> loader) {
// TODO: Loader reset, so we can clear out our existing data.
}
}
public class EarthquakeLoader extends AsyncTaskLoader<List<Earthquake>> {
public EarthquakeLoader(Context context, String url) {
super(context);
// TODO: Finish implementing this constructor
}
@Override
protected void onStartLoading() {
forceLoad();
}
@Override
public List<Earthquake> loadInBackground() {
// TODO: Implement this method
}
}
@martynaskairys
Copy link

good example

@bilijo
Copy link

bilijo commented Jun 30, 2017

What about LoaderManager.LoaderCallbacks instead of LoaderCallbacks ?

@MercyMarkus
Copy link

So my code refused to run, the Quake Report app kept crashing. After going through the log, I Saw a line that said something about "adding app permission for the network state" i.e by <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
Wondering if anyone else had to do this for their app to run?

@gautam123can
Copy link

In AndroidManifest.xml add permission. The code should look like below:

<uses-permission android:name="android.permission.INTERNET"/>

<application
    android:allowBackup="true"

.....
.....
.....
Please let me know if it works. Also, in EarthquakeActivity.java, USGS_REQUEST_URL should start with https and not http.

Thanks!

Copy link

ghost commented Aug 11, 2017

@bilijo basically there are two LoaderCallbacks in Android 1-> LoaderManager.LoadCallbacks and 2-> android.support.v4.app.LoaderManager.LoaderCallbacks, Note the second LoaderManager is from support library So, the full name is used to avoid the conflict but if you're not targeting the lower android API below 23 your studio will not complain about the conflict because it only gets the one LoaderCallbacks which is from android.app and for API 23 and above, correct me if I'm wrong as I'm also a beginner in android :)

@divineCodeNinja
Copy link

I do not know how to go about this task of adding loader to my Earthquake App.please help!

@paeybu
Copy link

paeybu commented May 22, 2019

Basically, just move what you did in AsyncTask's doInBackground() to loadInBackground()
and onPostExecute to onLoadFinished
and pass in the Url from the activity via the constructor when you define the new EarthquakeLoader

@bkeuria1
Copy link

bkeuria1 commented Jul 9, 2019

Is there any reason why we made AsynTask an anonymous class of the Earthquake activity but AsyncTaskLoader is its own class?

@Siddharth2110
Copy link

Is there any link to the code after this Loader class. I am not able to change AsyncTask to AsyncLoader class.

@Vestige-inc
Copy link

I don't understand why i'm getting this log error.

error: incompatible types: EarthquakeLoader cannot be converted to Loader<List>

This is my EarthquakeActivity:

public class EarthquakeActivity extends AppCompatActivity implements LoaderCallbacks<List> {

private static final int EARTHQUAKE_LOADER_ID = 1;

private static final String LOG_TAG = EarthquakeLoader.class.getName();

private TextView mEmptyStateTextView;

private EarthquakeAdapter mAdapter;

private static final String USGS_REQUEST_URL =
        "https://earthquake.usgs.gov/fdsnws/event/1/query?format=geojson&orderby=time&minmag=5&limit=10";

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.earthquake_activity);


    // Get a reference to the LoaderManager, in order to interact with loaders.
    LoaderManager loaderManager = getLoaderManager();

    // Initialize the loader. Pass in the int ID constant defined above and pass in null for
    // the bundle. Pass in this activity for the LoaderCallbacks parameter (which is valid
    // because this activity implements the LoaderCallbacks interface).
    loaderManager.initLoader(EARTHQUAKE_LOADER_ID, null, this);

    // Get a reference to the ConnectivityManager to check state of network connectivity
    ConnectivityManager connMgr = (ConnectivityManager)
            getSystemService(Context.CONNECTIVITY_SERVICE);

    // Get details on the currently active default data network
    NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();

    if (networkInfo == null ) {

//state that there is no internet connection
mEmptyStateTextView.setText(R.string.no_internet);
} else if (networkInfo!=null && networkInfo.isConnected()){
//There is internet but list is still empty
mEmptyStateTextView.setText(R.string.empty_list);
}

    // Find a reference to the {@link ListView} in the layout
    ListView earthquakeListView = (ListView) findViewById(R.id.list);

    // Create a new adapter that takes an empty list of earthquakes as input
    mAdapter = new EarthquakeAdapter(this, new ArrayList<Earthquake>());

    // Set the adapter on the {@link ListView}
    // so the list can be populated in the user interface
    earthquakeListView.setAdapter(mAdapter);

    // Set an item click listener on the ListView, which sends an intent to a web browser
    // to open a website with more information about the selected earthquake.
    earthquakeListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
            // Find the current earthquake that was clicked on
            Earthquake currentEarthquake = mAdapter.getItem(position);

            // Convert the String URL into a URI object (to pass into the Intent constructor)
            Uri earthquakeUri = Uri.parse(currentEarthquake.getUrl());

            // Create a new intent to view the earthquake URI
            Intent websiteIntent = new Intent(Intent.ACTION_VIEW, earthquakeUri);

            // Send the intent to launch a new activity
            startActivity(websiteIntent);
        }
    });

    mEmptyStateTextView = (TextView) findViewById(R.id.empty_view);
    earthquakeListView.setEmptyView(mEmptyStateTextView);


}


@Override
public Loader<List<Earthquake>> onCreateLoader(int i, Bundle bundle) {
    // Create a new loader for the given URL

    Log.e(LOG_TAG,"Test Oncreate Loader called .....");
    return  new EarthquakeLoader(this,USGS_REQUEST_URL);;
}

@Override
public void onLoadFinished(Loader<List<Earthquake>> loader, List<Earthquake> earthquakes) {
    // Clear the adapter of previous earthquake data
    mAdapter.clear();

    View loadingIndicator = findViewById(R.id.loading_indicator);
    loadingIndicator.setVisibility(View.GONE);

    mEmptyStateTextView.setText(R.string.no_earthquakes);

    // If there is a valid list of {@link Earthquake}s, then add them to the adapter's
    // data set. This will trigger the ListView to update.
    if (earthquakes != null && !earthquakes.isEmpty()) {
        mAdapter.addAll(earthquakes);
    }


}

@Override
public void onLoaderReset(Loader<List<Earthquake>> loader) {
    // Loader reset, so we can clear out our existing data.
    mAdapter.clear();
}



}

@JVJplus
Copy link

JVJplus commented Jan 16, 2020

Full Solution is available here! udacity/ud843-QuakeReport@6ac53a7?diff=split

@KyawYe-Htut
Copy link

Please make an update for deprecated android class like this Loader lesson.
So do for many other out dated lessons.Thank a lot .

@KyawYe-Htut
Copy link

KyawYe-Htut commented Jul 5, 2020

loaderManager.initLoader(EARTHQUAKE_LOADER_ID,null, this).forceLoad();

//this is not valid right now . The ide request callback instead of this .What do I do?

@josikie
Copy link

josikie commented Jul 10, 2020

@KyawYe-Htut
use this code in the onCreate method in EarthquakeActivity :
LoaderManager loaderManager = getSupportLoaderManager();
loaderManager.initLoader(1, null, this);

don't use forceLoad() in EarthquakeActivity, use forceLoad() in EarthquakeLoader, ps : sorry my english bad:)

@tahilbansal
Copy link

The below things worked for me.

Step -1: Make the changes as in udacity/ud843-QuakeReport@6ac53a7?diff=split

Step -2 : use this code in the onCreate method instead of EarthquakeActivity class :
LoaderManager loaderManager = getLoaderManager();
loaderManager.initLoader(1, null, this);

Step -3: Declare EarthqaukeLoader class as static as given below
public static class EarthquakeLoader extends AsyncTaskLoader<List>

@abdullahMorsi
Copy link

What about LoaderManager.LoaderCallbacks instead of LoaderCallbacks ?

Same

@Rohit570k
Copy link

Rohit570k commented Sep 28, 2021

Is there any reason why we made AsynTask an anonymous class of the Earthquake activity but AsyncTaskLoader is its own class?

so that we don't need to instantiate it for working and making inner class it can access parent class member and function directly,
in loader, we have callback method for establishing a connection that's why prefer to make a new class there

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment