Skip to content

Instantly share code, notes, and snippets.

@Rayne
Created August 4, 2013 19:18
Show Gist options
  • Save Rayne/6151554 to your computer and use it in GitHub Desktop.
Save Rayne/6151554 to your computer and use it in GitHub Desktop.
package com.example.test_loader;
import java.util.Calendar;
import android.app.Activity;
import android.app.LoaderManager;
import android.app.LoaderManager.LoaderCallbacks;
import android.content.AsyncTaskLoader;
import android.content.Context;
import android.content.Loader;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
/**
* <p><strong>App</strong> Shows a {@link Button} which is clickable. Clicking replaces the
* {@link Loader} with a new one. When {@link LoaderCallbacks#onLoadFinished(Loader, Object)}
* gets called, the UI gets updated to show the update's time stamp.</p>
*
* <p><strong>Problem</strong> The {@link Loader} does some "heavy lifting" and requires at least
* 4000ms. Changing the orientation while waiting for an successful update lets the app forget the
* old time stamp and shows the initial message.</p>
*
* <p>(The real app has a {@link Loader} which queries data from a database and then processes it.
* Serializing and throwing the data into a {@link Bundle} is no option.)</p>
*/
public class MainActivity extends Activity implements LoaderCallbacks<String> {
private static final String LOG_TAG = MainActivity.class.getSimpleName();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LoaderManager.enableDebugLogging(true);
final LoaderManager lm = getLoaderManager();
lm.initLoader(0, null, this);
/**
* The button which restarts loaders.
*/
findViewById(R.id.button1).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
lm.restartLoader(0, null, MainActivity.this);
}
});
}
/**
* FIXME Fix missing time when loading and changing orientation.
* Workaround: Pass old data to new {@link Loader} and let it deliver the old data first?
*/
@Override
public Loader<String> onCreateLoader(int id, Bundle args) {
return new MyLoader(getApplicationContext());
}
@Override
public void onLoadFinished(Loader<String> loader, String result) {
TextView t = (TextView) findViewById(R.id.text1);
t.setText(result);
}
/**
* FIXME Rescue old content? Force pull cached data from the loader?
*/
@Override
public void onLoaderReset(Loader<String> loaderWithStringDebugInformation) {
Log.d(LOG_TAG, "onLoaderReset(" + loaderWithStringDebugInformation.toString() + ")");
}
}
/**
* The loader which loads complex data (a {@link String}!).
*/
class MyLoader extends AsyncTaskLoader<String> {
String mCache = null;
public MyLoader(Context context) {
super(context.getApplicationContext());
}
@Override
protected void onStartLoading() {
super.onStartLoading();
if (mCache == null) {
forceLoad();
}
else {
deliverResult(mCache);
}
}
@Override
public void deliverResult(String data) {
mCache = data;
super.deliverResult(data);
}
@Override
public String loadInBackground() {
try {
Thread.sleep(4000); // Heavy lifting.
}
catch (InterruptedException e) {
/* NOOP */
}
Calendar c = Calendar.getInstance();
return c.get(Calendar.HOUR_OF_DAY) + ":" + c.get(Calendar.MINUTE) + ":" + c.get(Calendar.SECOND);
}
@Override
public String toString() {
return "MyLoader [mCache=" + mCache + "]";
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment