I have a FragmentActivity
that shows a contacts list.
Here is my onCreate
method:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_human_list);
if (findViewById(R.id.human_detail_container) != null) {
// The detail container view will be present only in the
// large-screen layouts (res/values-large and
// res/values-sw600dp). If this view is present, then the
// activity should be in two-pane mode.
mTwoPane = true;
// In two-pane mode, list items should be given the
// 'activated' state when touched.
((HumanListFragment) getSupportFragmentManager()
.findFragmentById(R.id.human_list))
.setActivateOnItemClick(true);
}
if (savedInstanceState == null || !savedInstanceState.getBoolean("displayed_contacts"))
displayContacts();
}
My onSaveInstanceState
:
@Override
protected void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
savedInstanceState.putBoolean("displayed_contacts", true);
}
And I'm not sure if this is relevant, but here's my displayContacts
just in case:
private void displayContacts() {
// Init variables
String[] SelectColumns = new String[] { Contacts._ID, Contacts.DISPLAY_NAME_PRIMARY, Contacts.PHOTO_URI };
String rawContactID, displayName, phoneNumber;
InputStream thumbnailPhoto;
Cursor c, infoC;
// Outer cursor (fetches all contact IDs)
c = getContentResolver().query(
Contacts.CONTENT_URI,
SelectColumns,
Contacts.HAS_PHONE_NUMBER + " = 1 ",
null,
Contacts.DISPLAY_NAME_PRIMARY);
Log.v(getPackageName(), "Found " + (c != null ? c.getCount() : "0") + " contacts");
try {
if (c.moveToFirst()) {
do {
// Columns
rawContactID = c.getString(c.getColumnIndex(SelectColumns[0]));
displayName = c.getString(c.getColumnIndex(SelectColumns[1]));
String[] selectPhone = {CommonDataKinds.Phone.NUMBER};
thumbnailPhoto = openThumbnail(Long.valueOf(rawContactID));
infoC = getContentResolver().query(
CommonDataKinds.Phone.CONTENT_URI,
selectPhone,
CommonDataKinds.Phone.CONTACT_ID + " = ?",
new String[] {rawContactID},
null
);
infoC.moveToFirst();
phoneNumber = infoC.getString(0);
// Adds items to ListView
HumanContent.addItem(new HumanContent.HumanItem(rawContactID, displayName, phoneNumber != "n/a" ? phoneNumber : "", thumbnailPhoto));
Log.v(getPackageName(), "Cursor position: " + c.getPosition() + ", contact ID: " + rawContactID);
infoC.close();
} while (c.moveToNext());
c.close();
}
displayed_contacts = true;
} catch (Exception e) {
Log.e(getPackageName(), e.getMessage());
}
}
Now here's the thing:
When I use the back key to exit the application, and then open it again via the icon; the list recreates itself even though it is saved in memory: so I get a double list of contacts on the same view.
savedInstanceState
is null in that case, so the if condition is reached, but in reality the view already has my previous contact list. What gives? How can I avoid recreating the list? I already tried using instance variables instead, but to no avail.
I'd also like to avoid recreating the list 100% of the times - if I can reuse the existing view, awesome.
First, the reason your savedInstanceState is null - The system only saves state of activities that are destroyed due to system constraints. If you back out of an Activity it is destroyed for good, and no state will be saved.
Relevant docs: http://developer.android.com/training/basics/activity-lifecycle/recreating.html
When your activity is destroyed because the user presses Back or the activity finishes itself, the system's concept of that Activity instance is gone forever because the behavior indicates the activity is no longer needed. However, if the system destroys the activity due to system constraints (rather than normal app behavior), then although the actual Activity instance is gone, the system remembers that it existed such that if the user navigates back to it, the system creates a new instance of the activity using a set of saved data that describes the state of the activity when it was destroyed.
So, it seems like your particular problem is that while your Activity is gone, your static HumanContact class is still in memory, and your new Activity is loading it with another copy of your contacts.
There are a couple ways you could solve this. First, you could implement a method on HumanContent to clear out all its items, and call it whenever you launch a new instance of your Activity. This would have the benefit of ensuring your data is up to date, but would mean you have to reload your contacts.
Secondly, if you wanted to truly avoid reloading the data, I'd recommend creating some sort of cache for the contacts that is independent of the Activity. You should consider your Activity as fairly transient, it can and will be destroyed and recreated frequently, whereas a cache can persist.
HumanContent seems to be filling this responsibility already, to an extent. You're using it to store your data, and it is persisting beyond the lifecycle of your Activity. You could additionally add a method to it that checks to see if it has contacts loaded, and if not loads them itself. This way it has complete control over loading and caching your data, and Activities can be responsible solely for the display of this data. Be careful with this type of solution that you're not storing too much data in memory, that you're reloading your cache anytime you expect your data to have changed, and be aware that your process might be restarted by the system in some cases, so your cache must be prepared to reload your data in case it is destroyed.
As for preserving your Views, if the user is backing out of your Activity then the finish() is being called, and your Activity is going to be destroyed. Remember, in this case the system no longer has any concept of the Activity, so there will be no way to preserve these views for reuse.
Its simple. follow these steps in your Activity
Then definitely you wont get content replication.
It is always adviced to use caching to retain the data . as mentiond by Groucho u can go with storage options Check below link for details.
http://developer.android.com/guide/topics/data/data-storage.html
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With