Skip to content

Instantly share code, notes, and snippets.

@chydee
Created June 10, 2019 08:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chydee/deed409e1fe34cdbd103177f0671a9be to your computer and use it in GitHub Desktop.
Save chydee/deed409e1fe34cdbd103177f0671a9be to your computer and use it in GitHub Desktop.
A Dummy's guide to AsycTaskLoader
#Step by step tutorial on how to define and use AsyncTaskLoader.
**************************************************************
This class performs the same function as the AsyncTask, but a bit better.
It can handle Activity configuration changes more easily, and it behaves within the life cycles of Fragments and Activities.
STEP 1: Implement LoaderManager.LoaderCallbacks<String> on MainActivity then implement and override the following methods:
onCreateLoader, onLoadFinished and onLoaderReset
STEP 2: Inside onCreateLoader() return a new AsyncTaskLoader<String> as an anonymous inner class with this as the constructor's parameter and override loadInBackground & onStartLoadinginside anonymous inner class
STEP 3: In your MainActivity define two constant
//TODO: (1)Integer constant to uniquely identify our Loader
//TODO: (2)String constant which will act as a key to pass data to Loader
STEP 4: Inside loadInBackground make a network call using HTTPUrlConnection or OKHttp or any other library.
You can perform any task that can potentially block the main UI thread here.
STEP 5: Inside onCreate initialize the loader with OPERATION_SEARCH_LOADER as the ID, null for the bundle, and this for the context
STEP 6: Now call this method, whenever and wherever you want to trigger the loader
STEP 7: SuperCharging(Caching) your Loader.
To handle the orientation change and avoiding creating duplicate request follow these steps.
//TODO: (1)Create a member variable inside AsyncTaskLoader to store the cached result in
//TODO: (2)Modify onStartLoading to just call deliverResult if the cache isn't null
//TODO: (3)Override deliverResult to store the data in our cache member variable
And we are done! Please if you find this article intriguing or helpful do share and like.
Meanwhile checkout other articles in this series.
//We want our AsyncTaskLoader to return a string on completion of the task that's why,
//we have set the generic type in LoaderManager.LoaderCallbacks<T> to be String
public class MainActivity extends AppCompatActivity
implements LoaderManager.LoaderCallbacks<String>{
//...
@Override
public Loader<String> onCreateLoader(int id, Bundle args) {
//Here we will initiate AsyncTaskLoader and handle the task in the background
return null;
}
@Override
public void onLoadFinished(Loader<String> loader, String data) {
//After getting the result we will update our UI here
}
@Override
public void onLoaderReset(Loader<String> loader) {
//Leave it for now as it is
}
}
@Override
public String loadInBackground() {
String url = args.getString(OPERATION_URL_EXTRA);//This is a url in string form (constant we have defined already)
if (url == null && "".equals(url)) {
return null;//if url is null, return
}
String operationResultString="";
try {
operationResultString = NetworkUtils.getResponseFromHttpUrl(url);
//This just create a HTTPUrlConnection and
//return result in strings
} catch (IOException e) {
e.printStackTrace();
}
return operationResultString;
}
private void makeOperationSearchQuery(String url) {
// Create a bundle called queryBundle
Bundle queryBundle = new Bundle();
// Use putString with OPERATION_QUERY_URL_EXTRA as the key and the String value of the URL as the value
//url value here is https://jsonplaceholder.typicode.com/posts
queryBundle.putString(OPERATION_QUERY_URL_EXTRA,url);
// Call getSupportLoaderManager and store it in a LoaderManager variable
LoaderManager loaderManager = getSupportLoaderManager();
// Get our Loader by calling getLoader and passing the ID we specified
Loader<String> loader = loaderManager.getLoader(OPERATION_SEARCH_LOADER);
// If the Loader was null, initialize it. Else, restart it.
if(loader==null){
loaderManager.initLoader(OPERATION_SEARCH_LOADER, queryBundle, this);
}else{
loaderManager.restartLoader(OPERATION_SEARCH_LOADER, queryBundle, this);
}
}
//your call will look like this
//makeOperationSearchQuery("https://jsonplaceholder.typicode.com/posts");
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
//...
/*OPERATION_SEARCH_LOADER is a constant we have defined to uniquely identify our loader
*which will be used in case of orientation change or cancelling our Loader */
getSupportLoaderManager().initLoader(OPERATION_SEARCH_LOADER, null, this);
}
@Override
public Loader<String> onCreateLoader(int id, final Bundle args) {
return new AsyncTaskLoader<String>(this) {
@Override
public String loadInBackground() {
//Think of this as AsyncTask doInBackground() method, here you will actually initiate Network call or any work
//that needs to be done on the background
return null;
}
@Override
protected void onStartLoading() {
//Think of this as AsyncTask onPreExecute() method,you can start your progress bar,and at the end call
//forceLoad();
forceLoad();
}
};
}
@Override
public Loader<String> onCreateLoader(int id, final Bundle args) {
return new AsyncTaskLoader<String>(this) {
String resultFromHttp; //This work as a cache variable
//...
@Override
protected void onStartLoading() {
if (resultFromHttp!=null) {
//To skip loadInBackground call
deliverResult(resultFromHttp);
}else{
forceLoad();
}
}
@Override
public void deliverResult(String data) {
resultFromHttp = data;
super.deliverResult(data);
}
};
}
public class MainActivity extends AppCompatActivity
implements LoaderManager.LoaderCallbacks<String>{
public static final int OPERATION_SEARCH_LOADER = 22;
public static final String OPERATION_URL_EXTRA = "url_that_return_json_data";
//...}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment