Drastically improve performance after installs/uninstalls.
- Only reload those apps that actually need reloading, not all of them - Reloading all the stuff inside DB.App is not necessary - only the install information can be changed
This commit is contained in:
parent
d39047bfea
commit
9c4aa9127f
@ -510,7 +510,7 @@ public class AppDetails extends ListActivity {
|
||||
new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog,
|
||||
int whichButton) {
|
||||
install();
|
||||
install(app.id);
|
||||
}
|
||||
});
|
||||
ask_alrt.setNegativeButton(getString(R.string.no),
|
||||
@ -523,7 +523,7 @@ public class AppDetails extends ListActivity {
|
||||
AlertDialog alert = ask_alrt.create();
|
||||
alert.show();
|
||||
} else
|
||||
install();
|
||||
install(app.id);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -601,7 +601,7 @@ public class AppDetails extends ListActivity {
|
||||
// Note that this handles updating as well as installing.
|
||||
curapk = app.getCurrentVersion();
|
||||
if (curapk != null)
|
||||
install();
|
||||
install(app.id);
|
||||
return true;
|
||||
|
||||
case UNINSTALL:
|
||||
@ -641,7 +641,7 @@ public class AppDetails extends ListActivity {
|
||||
}
|
||||
|
||||
// Install the version of this app denoted by 'curapk'.
|
||||
private void install() {
|
||||
private void install(final String id) {
|
||||
|
||||
String ra = null;
|
||||
try {
|
||||
@ -666,7 +666,7 @@ public class AppDetails extends ListActivity {
|
||||
public void onClick(DialogInterface dialog,
|
||||
int whichButton) {
|
||||
downloadHandler = new DownloadHandler(curapk,
|
||||
repoaddress);
|
||||
repoaddress, id);
|
||||
}
|
||||
});
|
||||
ask_alrt.setNegativeButton(getString(R.string.no),
|
||||
@ -694,7 +694,7 @@ public class AppDetails extends ListActivity {
|
||||
alert.show();
|
||||
return;
|
||||
}
|
||||
downloadHandler = new DownloadHandler(curapk, repoaddress);
|
||||
downloadHandler = new DownloadHandler(curapk, repoaddress, id);
|
||||
}
|
||||
|
||||
private void removeApk(String id) {
|
||||
@ -708,17 +708,15 @@ public class AppDetails extends ListActivity {
|
||||
Uri uri = Uri.fromParts("package", pkginfo.packageName, null);
|
||||
Intent intent = new Intent(Intent.ACTION_DELETE, uri);
|
||||
startActivityForResult(intent, REQUEST_UNINSTALL);
|
||||
((FDroidApp) getApplication()).invalidateApps();
|
||||
|
||||
}
|
||||
|
||||
private void installApk(File file) {
|
||||
private void installApk(File file, String id) {
|
||||
Intent intent = new Intent();
|
||||
intent.setAction(android.content.Intent.ACTION_VIEW);
|
||||
intent.setDataAndType(Uri.parse("file://" + file.getPath()),
|
||||
"application/vnd.android.package-archive");
|
||||
startActivityForResult(intent, REQUEST_INSTALL);
|
||||
((FDroidApp) getApplication()).invalidateApps();
|
||||
}
|
||||
|
||||
private void launchApk(String id) {
|
||||
@ -755,8 +753,10 @@ public class AppDetails extends ListActivity {
|
||||
private Downloader download;
|
||||
private ProgressDialog pd;
|
||||
private boolean updating;
|
||||
private String id;
|
||||
|
||||
public DownloadHandler(DB.Apk apk, String repoaddress) {
|
||||
public DownloadHandler(DB.Apk apk, String repoaddress, String appid) {
|
||||
id = appid;
|
||||
download = new Downloader(apk, repoaddress);
|
||||
download.start();
|
||||
startUpdates();
|
||||
@ -794,7 +794,7 @@ public class AppDetails extends ListActivity {
|
||||
case DONE:
|
||||
if (pd != null)
|
||||
pd.dismiss();
|
||||
installApk(download.localFile());
|
||||
installApk(download.localFile(), id);
|
||||
finished = true;
|
||||
break;
|
||||
case CANCELLED:
|
||||
|
@ -653,6 +653,17 @@ public class DB {
|
||||
}
|
||||
}
|
||||
|
||||
// Repopulate the details for the given app.
|
||||
// If 'apkrepo' is non-zero, only apks from that repo are
|
||||
// populated.
|
||||
public void repopulateDetails(App app, int apkRepo) {
|
||||
populateAppDetails(app);
|
||||
|
||||
for (Apk apk : app.apks) {
|
||||
populateApkDetails(apk, apkRepo);
|
||||
}
|
||||
}
|
||||
|
||||
// Return a list of apps matching the given criteria. Filtering is
|
||||
// also done based on compatibility and anti-features according to
|
||||
// the user's current preferences.
|
||||
@ -784,6 +795,57 @@ public class DB {
|
||||
return result;
|
||||
}
|
||||
|
||||
public List<App> refreshApps(List<App> apps, List<String> invalidApps) {
|
||||
|
||||
List<PackageInfo> installedPackages = mContext.getPackageManager()
|
||||
.getInstalledPackages(0);
|
||||
long startTime = System.currentTimeMillis();
|
||||
for (String appid : invalidApps) {
|
||||
App app = null;
|
||||
int index = -1;
|
||||
for (App oldapp : apps) {
|
||||
index++;
|
||||
if (oldapp.id.equals(appid)) {
|
||||
app = oldapp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (app == null) continue;
|
||||
|
||||
PackageInfo installed = null;
|
||||
|
||||
for (PackageInfo appInfo : installedPackages) {
|
||||
if (appInfo.packageName.equals(appid)) {
|
||||
installed = appInfo;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (installed != null) {
|
||||
app.installedVersion = installed.versionName;
|
||||
app.installedVerCode = installed.versionCode;
|
||||
} else {
|
||||
app.installedVersion = null;
|
||||
app.installedVerCode = 0;
|
||||
}
|
||||
|
||||
Apk curver = app.getCurrentVersion();
|
||||
if (curver != null
|
||||
&& app.installedVersion != null
|
||||
&& app.installedVerCode < curver.vercode) {
|
||||
app.hasUpdates = true;
|
||||
app.updateVersion = curver.version;
|
||||
}
|
||||
|
||||
apps.set(index, app);
|
||||
}
|
||||
Log.d("FDroid", "Refreshing " + invalidApps.size() + " apps took "
|
||||
+ (System.currentTimeMillis() - startTime) + " ms");
|
||||
|
||||
return apps;
|
||||
}
|
||||
|
||||
public List<String> doSearch(String query) {
|
||||
|
||||
List<String> ids = new ArrayList<String>();
|
||||
|
@ -65,6 +65,7 @@ public class FDroidApp extends Application {
|
||||
icon_path.mkdir();
|
||||
|
||||
apps = null;
|
||||
invalidApps = new ArrayList<String>();
|
||||
Context ctx = getApplicationContext();
|
||||
DB.initDB(ctx);
|
||||
UpdateService.schedule(ctx);
|
||||
@ -76,15 +77,16 @@ public class FDroidApp extends Application {
|
||||
|
||||
// Set when something has changed (database or installed apps) so we know
|
||||
// we should invalidate the apps.
|
||||
private volatile boolean appsInvalid = false;
|
||||
private volatile boolean appsAllInvalid = false;
|
||||
private Semaphore appsInvalidLock = new Semaphore(1, false);
|
||||
private List<String> invalidApps;
|
||||
|
||||
// Set apps invalid. Call this when the database has been updated with
|
||||
// new app information, or when the installed packages have changed.
|
||||
public void invalidateApps() {
|
||||
public void invalidateAllApps() {
|
||||
try {
|
||||
appsInvalidLock.acquire();
|
||||
appsInvalid = true;
|
||||
appsAllInvalid = true;
|
||||
} catch (InterruptedException e) {
|
||||
// Don't care
|
||||
} finally {
|
||||
@ -92,6 +94,12 @@ public class FDroidApp extends Application {
|
||||
}
|
||||
}
|
||||
|
||||
// Invalidate a single app
|
||||
public void invalidateApp(String id) {
|
||||
Log.d("FDroid", "Invalidating "+id);
|
||||
invalidApps.add(id);
|
||||
}
|
||||
|
||||
// Get a list of all known applications. Should not be called when the
|
||||
// database is locked (i.e. between DB.getDB() and db.releaseDB(). The
|
||||
// contents should never be modified, it's for reading only.
|
||||
@ -100,9 +108,9 @@ public class FDroidApp extends Application {
|
||||
boolean invalid = false;
|
||||
try {
|
||||
appsInvalidLock.acquire();
|
||||
invalid = appsInvalid;
|
||||
invalid = appsAllInvalid;
|
||||
if (invalid) {
|
||||
appsInvalid = false;
|
||||
appsAllInvalid = false;
|
||||
Log.d("FDroid", "Dropping cached app data");
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
@ -118,6 +126,14 @@ public class FDroidApp extends Application {
|
||||
} finally {
|
||||
DB.releaseDB();
|
||||
}
|
||||
} else if (!invalidApps.isEmpty()) {
|
||||
try {
|
||||
DB db = DB.getDB();
|
||||
apps = db.refreshApps(apps, invalidApps);
|
||||
invalidApps.clear();
|
||||
} finally {
|
||||
DB.releaseDB();
|
||||
}
|
||||
}
|
||||
if (apps == null)
|
||||
return new ArrayList<DB.App>();
|
||||
|
@ -27,8 +27,9 @@ public class PackageReceiver extends BroadcastReceiver {
|
||||
|
||||
@Override
|
||||
public void onReceive(Context ctx, Intent intent) {
|
||||
Log.d("FDroid", "PackageReceiver invalidating apps");
|
||||
((FDroidApp) ctx.getApplicationContext()).invalidateApps();
|
||||
String appid = intent.getData().getSchemeSpecificPart();
|
||||
Log.d("FDroid", "PackageReceiver invalidating "+appid);
|
||||
((FDroidApp) ctx.getApplicationContext()).invalidateApp(appid);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -74,7 +74,7 @@ public class Preferences extends PreferenceActivity implements
|
||||
} finally {
|
||||
DB.releaseDB();
|
||||
}
|
||||
((FDroidApp) getApplication()).invalidateApps();
|
||||
((FDroidApp) getApplication()).invalidateAllApps();
|
||||
|
||||
File dp = DB.getDataPath();
|
||||
deleteAll(dp);
|
||||
|
@ -248,7 +248,7 @@ public class UpdateService extends IntentService implements ProgressListener {
|
||||
sendStatus(STATUS_INFO, getString(R.string.status_downloading_icons));
|
||||
for (DB.App app : acceptedapps)
|
||||
getIcon(app, repos);
|
||||
((FDroidApp) getApplication()).invalidateApps();
|
||||
((FDroidApp) getApplication()).invalidateAllApps();
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user