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() {
|
new DialogInterface.OnClickListener() {
|
||||||
public void onClick(DialogInterface dialog,
|
public void onClick(DialogInterface dialog,
|
||||||
int whichButton) {
|
int whichButton) {
|
||||||
install();
|
install(app.id);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
ask_alrt.setNegativeButton(getString(R.string.no),
|
ask_alrt.setNegativeButton(getString(R.string.no),
|
||||||
@ -523,7 +523,7 @@ public class AppDetails extends ListActivity {
|
|||||||
AlertDialog alert = ask_alrt.create();
|
AlertDialog alert = ask_alrt.create();
|
||||||
alert.show();
|
alert.show();
|
||||||
} else
|
} else
|
||||||
install();
|
install(app.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -601,7 +601,7 @@ public class AppDetails extends ListActivity {
|
|||||||
// Note that this handles updating as well as installing.
|
// Note that this handles updating as well as installing.
|
||||||
curapk = app.getCurrentVersion();
|
curapk = app.getCurrentVersion();
|
||||||
if (curapk != null)
|
if (curapk != null)
|
||||||
install();
|
install(app.id);
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case UNINSTALL:
|
case UNINSTALL:
|
||||||
@ -641,7 +641,7 @@ public class AppDetails extends ListActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Install the version of this app denoted by 'curapk'.
|
// Install the version of this app denoted by 'curapk'.
|
||||||
private void install() {
|
private void install(final String id) {
|
||||||
|
|
||||||
String ra = null;
|
String ra = null;
|
||||||
try {
|
try {
|
||||||
@ -666,7 +666,7 @@ public class AppDetails extends ListActivity {
|
|||||||
public void onClick(DialogInterface dialog,
|
public void onClick(DialogInterface dialog,
|
||||||
int whichButton) {
|
int whichButton) {
|
||||||
downloadHandler = new DownloadHandler(curapk,
|
downloadHandler = new DownloadHandler(curapk,
|
||||||
repoaddress);
|
repoaddress, id);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
ask_alrt.setNegativeButton(getString(R.string.no),
|
ask_alrt.setNegativeButton(getString(R.string.no),
|
||||||
@ -694,7 +694,7 @@ public class AppDetails extends ListActivity {
|
|||||||
alert.show();
|
alert.show();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
downloadHandler = new DownloadHandler(curapk, repoaddress);
|
downloadHandler = new DownloadHandler(curapk, repoaddress, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void removeApk(String id) {
|
private void removeApk(String id) {
|
||||||
@ -708,17 +708,15 @@ public class AppDetails extends ListActivity {
|
|||||||
Uri uri = Uri.fromParts("package", pkginfo.packageName, null);
|
Uri uri = Uri.fromParts("package", pkginfo.packageName, null);
|
||||||
Intent intent = new Intent(Intent.ACTION_DELETE, uri);
|
Intent intent = new Intent(Intent.ACTION_DELETE, uri);
|
||||||
startActivityForResult(intent, REQUEST_UNINSTALL);
|
startActivityForResult(intent, REQUEST_UNINSTALL);
|
||||||
((FDroidApp) getApplication()).invalidateApps();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void installApk(File file) {
|
private void installApk(File file, String id) {
|
||||||
Intent intent = new Intent();
|
Intent intent = new Intent();
|
||||||
intent.setAction(android.content.Intent.ACTION_VIEW);
|
intent.setAction(android.content.Intent.ACTION_VIEW);
|
||||||
intent.setDataAndType(Uri.parse("file://" + file.getPath()),
|
intent.setDataAndType(Uri.parse("file://" + file.getPath()),
|
||||||
"application/vnd.android.package-archive");
|
"application/vnd.android.package-archive");
|
||||||
startActivityForResult(intent, REQUEST_INSTALL);
|
startActivityForResult(intent, REQUEST_INSTALL);
|
||||||
((FDroidApp) getApplication()).invalidateApps();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void launchApk(String id) {
|
private void launchApk(String id) {
|
||||||
@ -755,8 +753,10 @@ public class AppDetails extends ListActivity {
|
|||||||
private Downloader download;
|
private Downloader download;
|
||||||
private ProgressDialog pd;
|
private ProgressDialog pd;
|
||||||
private boolean updating;
|
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 = new Downloader(apk, repoaddress);
|
||||||
download.start();
|
download.start();
|
||||||
startUpdates();
|
startUpdates();
|
||||||
@ -794,7 +794,7 @@ public class AppDetails extends ListActivity {
|
|||||||
case DONE:
|
case DONE:
|
||||||
if (pd != null)
|
if (pd != null)
|
||||||
pd.dismiss();
|
pd.dismiss();
|
||||||
installApk(download.localFile());
|
installApk(download.localFile(), id);
|
||||||
finished = true;
|
finished = true;
|
||||||
break;
|
break;
|
||||||
case CANCELLED:
|
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
|
// Return a list of apps matching the given criteria. Filtering is
|
||||||
// also done based on compatibility and anti-features according to
|
// also done based on compatibility and anti-features according to
|
||||||
// the user's current preferences.
|
// the user's current preferences.
|
||||||
@ -784,6 +795,57 @@ public class DB {
|
|||||||
return result;
|
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) {
|
public List<String> doSearch(String query) {
|
||||||
|
|
||||||
List<String> ids = new ArrayList<String>();
|
List<String> ids = new ArrayList<String>();
|
||||||
|
@ -65,6 +65,7 @@ public class FDroidApp extends Application {
|
|||||||
icon_path.mkdir();
|
icon_path.mkdir();
|
||||||
|
|
||||||
apps = null;
|
apps = null;
|
||||||
|
invalidApps = new ArrayList<String>();
|
||||||
Context ctx = getApplicationContext();
|
Context ctx = getApplicationContext();
|
||||||
DB.initDB(ctx);
|
DB.initDB(ctx);
|
||||||
UpdateService.schedule(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
|
// Set when something has changed (database or installed apps) so we know
|
||||||
// we should invalidate the apps.
|
// we should invalidate the apps.
|
||||||
private volatile boolean appsInvalid = false;
|
private volatile boolean appsAllInvalid = false;
|
||||||
private Semaphore appsInvalidLock = new Semaphore(1, false);
|
private Semaphore appsInvalidLock = new Semaphore(1, false);
|
||||||
|
private List<String> invalidApps;
|
||||||
|
|
||||||
// Set apps invalid. Call this when the database has been updated with
|
// Set apps invalid. Call this when the database has been updated with
|
||||||
// new app information, or when the installed packages have changed.
|
// new app information, or when the installed packages have changed.
|
||||||
public void invalidateApps() {
|
public void invalidateAllApps() {
|
||||||
try {
|
try {
|
||||||
appsInvalidLock.acquire();
|
appsInvalidLock.acquire();
|
||||||
appsInvalid = true;
|
appsAllInvalid = true;
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
// Don't care
|
// Don't care
|
||||||
} finally {
|
} 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
|
// 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
|
// database is locked (i.e. between DB.getDB() and db.releaseDB(). The
|
||||||
// contents should never be modified, it's for reading only.
|
// contents should never be modified, it's for reading only.
|
||||||
@ -100,9 +108,9 @@ public class FDroidApp extends Application {
|
|||||||
boolean invalid = false;
|
boolean invalid = false;
|
||||||
try {
|
try {
|
||||||
appsInvalidLock.acquire();
|
appsInvalidLock.acquire();
|
||||||
invalid = appsInvalid;
|
invalid = appsAllInvalid;
|
||||||
if (invalid) {
|
if (invalid) {
|
||||||
appsInvalid = false;
|
appsAllInvalid = false;
|
||||||
Log.d("FDroid", "Dropping cached app data");
|
Log.d("FDroid", "Dropping cached app data");
|
||||||
}
|
}
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
@ -118,6 +126,14 @@ public class FDroidApp extends Application {
|
|||||||
} finally {
|
} finally {
|
||||||
DB.releaseDB();
|
DB.releaseDB();
|
||||||
}
|
}
|
||||||
|
} else if (!invalidApps.isEmpty()) {
|
||||||
|
try {
|
||||||
|
DB db = DB.getDB();
|
||||||
|
apps = db.refreshApps(apps, invalidApps);
|
||||||
|
invalidApps.clear();
|
||||||
|
} finally {
|
||||||
|
DB.releaseDB();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (apps == null)
|
if (apps == null)
|
||||||
return new ArrayList<DB.App>();
|
return new ArrayList<DB.App>();
|
||||||
|
@ -27,8 +27,9 @@ public class PackageReceiver extends BroadcastReceiver {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onReceive(Context ctx, Intent intent) {
|
public void onReceive(Context ctx, Intent intent) {
|
||||||
Log.d("FDroid", "PackageReceiver invalidating apps");
|
String appid = intent.getData().getSchemeSpecificPart();
|
||||||
((FDroidApp) ctx.getApplicationContext()).invalidateApps();
|
Log.d("FDroid", "PackageReceiver invalidating "+appid);
|
||||||
|
((FDroidApp) ctx.getApplicationContext()).invalidateApp(appid);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -74,7 +74,7 @@ public class Preferences extends PreferenceActivity implements
|
|||||||
} finally {
|
} finally {
|
||||||
DB.releaseDB();
|
DB.releaseDB();
|
||||||
}
|
}
|
||||||
((FDroidApp) getApplication()).invalidateApps();
|
((FDroidApp) getApplication()).invalidateAllApps();
|
||||||
|
|
||||||
File dp = DB.getDataPath();
|
File dp = DB.getDataPath();
|
||||||
deleteAll(dp);
|
deleteAll(dp);
|
||||||
|
@ -248,7 +248,7 @@ public class UpdateService extends IntentService implements ProgressListener {
|
|||||||
sendStatus(STATUS_INFO, getString(R.string.status_downloading_icons));
|
sendStatus(STATUS_INFO, getString(R.string.status_downloading_icons));
|
||||||
for (DB.App app : acceptedapps)
|
for (DB.App app : acceptedapps)
|
||||||
getIcon(app, repos);
|
getIcon(app, repos);
|
||||||
((FDroidApp) getApplication()).invalidateApps();
|
((FDroidApp) getApplication()).invalidateAllApps();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user