actually use iterator interface for ParcelableFileCache in activities

This commit is contained in:
Vincent Breitmoser 2014-10-03 04:06:44 +02:00
parent 04c8d42436
commit 504064302b
4 changed files with 52 additions and 19 deletions

View File

@ -39,6 +39,7 @@ import android.view.ViewGroup;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.api.OpenKeychainIntents;
import org.sufficientlysecure.keychain.ui.ImportKeysListFragment.IteratorWithSize;
import org.sufficientlysecure.keychain.ui.util.FormattingUtils;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import org.sufficientlysecure.keychain.util.Preferences;
@ -481,15 +482,17 @@ public class ImportKeysActivity extends ActionBarActivity {
Bundle data = new Bundle();
// get DATA from selected key entries
ArrayList<ParcelableKeyRing> selectedEntries = mListFragment.getSelectedData();
IteratorWithSize<ParcelableKeyRing> selectedEntries = mListFragment.getSelectedData();
// instead of given the entries by Intent extra, cache them into a file
// to prevent Java Binder problems on heavy imports
// instead of giving the entries by Intent extra, cache them into a
// file to prevent Java Binder problems on heavy imports
// read FileImportCache for more info.
try {
// We parcel this iteratively into a file - anything we can
// display here, we should be able to import.
ParcelableFileCache<ParcelableKeyRing> cache =
new ParcelableFileCache<ParcelableKeyRing>(this, "key_import.pcl");
cache.writeCache(selectedEntries.size(), selectedEntries.iterator());
cache.writeCache(selectedEntries.getSize(), selectedEntries);
intent.putExtra(KeychainIntentService.EXTRA_DATA, data);

View File

@ -48,6 +48,7 @@ import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class ImportKeysListFragment extends ListFragment implements
@ -74,12 +75,42 @@ public class ImportKeysListFragment extends ListFragment implements
return mAdapter.getData();
}
public ArrayList<ParcelableKeyRing> getSelectedData() {
ArrayList<ParcelableKeyRing> result = new ArrayList<ParcelableKeyRing>();
for (ImportKeysListEntry entry : getSelectedEntries()) {
result.add(mCachedKeyData.get(entry.hashCode()));
}
return result;
// Tuples would make this easier...
public static interface IteratorWithSize<E> extends Iterator<E> {
int getSize();
}
/** Returns an Iterator (with size) of the selected data items.
* This iterator is sort of a tradeoff, it's slightly more complex than an
* ArrayList would have been, but we save some memory by just returning
* relevant elements on demand.
*/
public IteratorWithSize<ParcelableKeyRing> getSelectedData() {
final ArrayList<ImportKeysListEntry> entries = getSelectedEntries();
final Iterator<ImportKeysListEntry> it = entries.iterator();
return new IteratorWithSize<ParcelableKeyRing>() {
@Override
public int getSize() {
return entries.size();
}
@Override
public boolean hasNext() {
return it.hasNext();
}
@Override
public ParcelableKeyRing next() {
// throws NoSuchElementException if it doesn't exist, but that's not our problem
return mCachedKeyData.get(it.next().hashCode());
}
@Override
public void remove() {
it.remove();
}
};
}
public ArrayList<ImportKeysListEntry> getSelectedEntries() {

View File

@ -41,7 +41,6 @@ import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@ -91,17 +90,13 @@ public class ImportKeysAdapter extends ArrayAdapter<ImportKeysListEntry> {
}
public ArrayList<ImportKeysListEntry> getSelectedEntries() {
ArrayList<ImportKeysListEntry> selectedData = new ArrayList<ImportKeysListEntry>();
// Nothing to select, nvm.
if (mData == null) {
return selectedData;
}
ArrayList<ImportKeysListEntry> result = new ArrayList<ImportKeysListEntry>();
for (ImportKeysListEntry entry : mData) {
if (entry.isSelected()) {
selectedData.add(entry);
result.add(entry);
}
}
return selectedData;
return result;
}
@Override

View File

@ -55,6 +55,10 @@ public class ParcelableFileCache<E extends Parcelable> {
mFilename = filename;
}
/** This method returns the number of entries as valid for the iterator
* received by the latest readCache operation. Yes, it is slightly
* peculiar.
*/
public int getNumEntries() {
return mNumEntries;
}
@ -107,7 +111,7 @@ public class ParcelableFileCache<E extends Parcelable> {
throw new IOException(e);
}
// yes this is slightly sloppy data flow. WE WOULDN'T NEED THIS WITH TUPLE RETURN TYPES
// yes this is sloppy data flow. WE WOULDN'T NEED THIS WITH TUPLE RETURN TYPES
mNumEntries = ois.readInt();
return new Iterator<E>() {