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

View File

@ -48,6 +48,7 @@ import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator;
import java.util.List; import java.util.List;
public class ImportKeysListFragment extends ListFragment implements public class ImportKeysListFragment extends ListFragment implements
@ -74,12 +75,42 @@ public class ImportKeysListFragment extends ListFragment implements
return mAdapter.getData(); return mAdapter.getData();
} }
public ArrayList<ParcelableKeyRing> getSelectedData() { // Tuples would make this easier...
ArrayList<ParcelableKeyRing> result = new ArrayList<ParcelableKeyRing>(); public static interface IteratorWithSize<E> extends Iterator<E> {
for (ImportKeysListEntry entry : getSelectedEntries()) { int getSize();
result.add(mCachedKeyData.get(entry.hashCode())); }
}
return result; /** 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() { public ArrayList<ImportKeysListEntry> getSelectedEntries() {

View File

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

View File

@ -55,6 +55,10 @@ public class ParcelableFileCache<E extends Parcelable> {
mFilename = filename; 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() { public int getNumEntries() {
return mNumEntries; return mNumEntries;
} }
@ -107,7 +111,7 @@ public class ParcelableFileCache<E extends Parcelable> {
throw new IOException(e); 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(); mNumEntries = ois.readInt();
return new Iterator<E>() { return new Iterator<E>() {