Use UIL, don't do caching on our own.
Advantages: * Initial setup time for icons is zero * We don't have to deal with it ourselves * We can use the default package icon while we load
This commit is contained in:
parent
0d6ec3a001
commit
017811fb92
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
[submodule "extern/Universal-Image-Loader"]
|
||||
path = extern/Universal-Image-Loader
|
||||
url = https://github.com/nostra13/Android-Universal-Image-Loader
|
1
extern/Universal-Image-Loader
vendored
Submodule
1
extern/Universal-Image-Loader
vendored
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 24ca7dd0dbaee8a011aad6195f33e840793e7df9
|
@ -2,3 +2,4 @@ proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.
|
||||
|
||||
target=android-18
|
||||
|
||||
android.library.reference.1=extern/Universal-Image-Loader/library
|
||||
|
@ -70,6 +70,8 @@ import android.widget.BaseAdapter;
|
||||
|
||||
import org.fdroid.fdroid.compat.PackageManagerCompat;
|
||||
|
||||
import com.nostra13.universalimageloader.core.ImageLoader;
|
||||
|
||||
public class AppDetails extends ListActivity {
|
||||
|
||||
private static final int REQUEST_INSTALL = 0;
|
||||
@ -406,12 +408,7 @@ public class AppDetails extends ListActivity {
|
||||
|
||||
// Set the icon...
|
||||
ImageView iv = (ImageView) findViewById(R.id.icon);
|
||||
File icon = new File(DB.getIconsPath(this), app.icon);
|
||||
if (icon.exists()) {
|
||||
iv.setImageDrawable(new BitmapDrawable(icon.getPath()));
|
||||
} else {
|
||||
iv.setImageResource(android.R.drawable.sym_def_app_icon);
|
||||
}
|
||||
ImageLoader.getInstance().displayImage(app.repoAddress+"/icons/"+app.icon, iv);
|
||||
|
||||
// Set the title and other header details...
|
||||
TextView tv = (TextView) findViewById(R.id.title);
|
||||
|
@ -125,6 +125,7 @@ public class DB {
|
||||
compatible = false;
|
||||
ignoreUpdates = false;
|
||||
filtered = false;
|
||||
repoAddress = null;
|
||||
}
|
||||
|
||||
// True when all the detail fields are populated, False otherwise.
|
||||
@ -207,6 +208,8 @@ public class DB {
|
||||
// List of apks.
|
||||
public List<Apk> apks;
|
||||
|
||||
public String repoAddress;
|
||||
|
||||
// Get the current version - this will be one of the Apks from 'apks'.
|
||||
// Can return null if there are no available versions.
|
||||
// This should be the 'current' version, as in the most recent stable
|
||||
@ -558,13 +561,6 @@ public class DB {
|
||||
return ContextCompat.create(ctx).getExternalCacheDir();
|
||||
}
|
||||
|
||||
public static File getIconsPath(Context ctx) {
|
||||
File dp = getDataPath(ctx);
|
||||
if (dp == null)
|
||||
return null;
|
||||
return new File(dp, "icons");
|
||||
}
|
||||
|
||||
private Context mContext;
|
||||
private Apk.CompatibilityChecker compatChecker = null;
|
||||
|
||||
|
@ -19,7 +19,6 @@
|
||||
package org.fdroid.fdroid;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FilenameFilter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Semaphore;
|
||||
@ -30,6 +29,13 @@ import android.util.Log;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
|
||||
import com.nostra13.universalimageloader.utils.StorageUtils;
|
||||
import com.nostra13.universalimageloader.cache.disc.impl.UnlimitedDiscCache;
|
||||
import com.nostra13.universalimageloader.cache.disc.naming.FileNameGenerator;
|
||||
import com.nostra13.universalimageloader.core.DisplayImageOptions;
|
||||
import com.nostra13.universalimageloader.core.ImageLoader;
|
||||
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
|
||||
|
||||
public class FDroidApp extends Application {
|
||||
|
||||
@Override
|
||||
@ -69,7 +75,22 @@ public class FDroidApp extends Application {
|
||||
ctx = getApplicationContext();
|
||||
DB.initDB(ctx);
|
||||
UpdateService.schedule(ctx);
|
||||
|
||||
|
||||
File cacheDir = new File(StorageUtils.getCacheDirectory(ctx), "icons");
|
||||
DisplayImageOptions defaultOptions = new DisplayImageOptions.Builder()
|
||||
.cacheInMemory(true)
|
||||
.cacheOnDisc(true)
|
||||
.showImageOnLoading(android.R.drawable.sym_def_app_icon)
|
||||
.showImageForEmptyUri(android.R.drawable.sym_def_app_icon)
|
||||
.build();
|
||||
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(ctx)
|
||||
.discCache(new UnlimitedDiscCache(cacheDir, new FileNameGenerator() {
|
||||
public String generate(String imageUri) {
|
||||
return imageUri.substring(imageUri.lastIndexOf('/') + 1);
|
||||
} } ))
|
||||
.defaultDisplayImageOptions(defaultOptions)
|
||||
.build();
|
||||
ImageLoader.getInstance().init(config);
|
||||
}
|
||||
|
||||
Context ctx;
|
||||
@ -125,6 +146,11 @@ public class FDroidApp extends Application {
|
||||
try {
|
||||
DB db = DB.getDB();
|
||||
apps = db.getApps(true);
|
||||
for (DB.Repo repo : db.getRepos())
|
||||
for (DB.App app : apps)
|
||||
if (repo.id == app.apks.get(0).repo)
|
||||
app.repoAddress = repo.address;
|
||||
|
||||
} finally {
|
||||
DB.releaseDB();
|
||||
}
|
||||
|
@ -255,38 +255,6 @@ public class UpdateService extends IntentService implements ProgressListener {
|
||||
|
||||
}
|
||||
|
||||
if (success) {
|
||||
File d = DB.getIconsPath(this);
|
||||
List<DB.App> toDownloadIcons = null;
|
||||
if (!d.exists()) {
|
||||
Log.d("FDroid", "Icons were wiped. Re-downloading all of them.");
|
||||
d.mkdirs();
|
||||
toDownloadIcons = ((FDroidApp) getApplication()).getApps();
|
||||
} else if (changes) {
|
||||
toDownloadIcons = acceptedapps;
|
||||
}
|
||||
if (toDownloadIcons != null) {
|
||||
|
||||
// Create a .nomedia file in the icons directory. For
|
||||
// recent Android versions this isn't necessary, because
|
||||
// they recognise the cache location. Older versions don't
|
||||
// though.
|
||||
File f = new File(d, ".nomedia");
|
||||
if (!f.exists()) {
|
||||
try {
|
||||
f.createNewFile();
|
||||
} catch (Exception e) {
|
||||
Log.d("FDroid", "Failed to create .nomedia");
|
||||
}
|
||||
}
|
||||
|
||||
sendStatus(STATUS_INFO,
|
||||
getString(R.string.status_downloading_icons));
|
||||
for (DB.App app : toDownloadIcons)
|
||||
getIcon(app, repos);
|
||||
}
|
||||
}
|
||||
|
||||
if (success && changes)
|
||||
((FDroidApp) getApplication()).invalidateAllApps();
|
||||
|
||||
@ -348,52 +316,6 @@ public class UpdateService extends IntentService implements ProgressListener {
|
||||
}
|
||||
}
|
||||
|
||||
private void getIcon(final DB.App app, List<DB.Repo> repos) {
|
||||
InputStream input = null;
|
||||
OutputStream output = null;
|
||||
try {
|
||||
|
||||
File f = new File(DB.getIconsPath(this), app.icon);
|
||||
if (f.exists())
|
||||
return;
|
||||
|
||||
if (app.apks.size() == 0)
|
||||
return;
|
||||
String server = null;
|
||||
for (DB.Repo repo : repos)
|
||||
if (repo.id == app.apks.get(0).repo)
|
||||
server = repo.address;
|
||||
if (server == null)
|
||||
return;
|
||||
|
||||
// Get it from the server...
|
||||
URL u = new URL(server + "/icons/" + app.icon);
|
||||
HttpURLConnection uc = (HttpURLConnection) u.openConnection();
|
||||
if (uc.getResponseCode() == 200) {
|
||||
|
||||
// Delete all other icons for the same app
|
||||
final File[] files = DB.getIconsPath(this).listFiles(
|
||||
new FilenameFilter() {
|
||||
@Override
|
||||
public boolean accept(final File d, final String n) {
|
||||
return n.matches(app.id+"\\.[0-9]+\\.png");
|
||||
}
|
||||
} );
|
||||
for (final File file : files) {
|
||||
if (!file.delete())
|
||||
Log.e("FDroid", "Cannot remove icon file " + file.getAbsolutePath());
|
||||
}
|
||||
|
||||
input = uc.getInputStream();
|
||||
output = new FileOutputStream(f);
|
||||
Utils.copy(input, output);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
} finally {
|
||||
Utils.closeQuietly(output);
|
||||
Utils.closeQuietly(input);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Received progress event from the RepoXMLHandler. It could be progress
|
||||
|
@ -17,6 +17,8 @@ import org.fdroid.fdroid.Preferences;
|
||||
import org.fdroid.fdroid.R;
|
||||
import org.fdroid.fdroid.compat.LayoutCompat;
|
||||
|
||||
import com.nostra13.universalimageloader.core.ImageLoader;
|
||||
|
||||
abstract public class AppListAdapter extends BaseAdapter {
|
||||
|
||||
private List<DB.App> items = new ArrayList<DB.App>();
|
||||
@ -77,7 +79,7 @@ abstract public class AppListAdapter extends BaseAdapter {
|
||||
summary.setText(app.summary);
|
||||
|
||||
layoutSummary(summary);
|
||||
layoutIcon(icon, app);
|
||||
ImageLoader.getInstance().displayImage(app.repoAddress+"/icons/"+app.icon, icon);
|
||||
|
||||
int visibleOnCompact = compact ? View.VISIBLE : View.GONE;
|
||||
int notVisibleOnCompact = compact ? View.GONE : View.VISIBLE;
|
||||
@ -118,22 +120,6 @@ abstract public class AppListAdapter extends BaseAdapter {
|
||||
return convertView;
|
||||
}
|
||||
|
||||
/**
|
||||
* If an icon exists on disc, we'll use that, otherwise default to the
|
||||
* plain android app icon.
|
||||
*/
|
||||
private void layoutIcon(ImageView iconView, DB.App app) {
|
||||
|
||||
File icn = new File(DB.getIconsPath(mContext), app.icon);
|
||||
if (icn.exists() && icn.length() > 0) {
|
||||
new Uri.Builder().build();
|
||||
iconView.setImageURI(Uri.parse(icn.getPath()));
|
||||
} else {
|
||||
iconView.setImageResource(android.R.drawable.sym_def_app_icon);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* In compact view, the summary sites next to the icon, below the name.
|
||||
* In non-compact view, it sits under the icon, with some padding pushing
|
||||
|
Loading…
x
Reference in New Issue
Block a user