Updater speed improvements during "Saving Application Details"
I've been able to reproduce #324 OutOfMemory errors on an emulator with 12MiB of heap space. This branch did _not_ have an OOM error when updating with F-Droid and F-Droid Archive repos enabled. They successfully update without problem.
Fixes#45.
The "Saving Application Details" stage of repository updating is where each apk has its suggested version calculated, icon URLs calculated, etc. These all require [correlated subqueries](https://en.wikipedia.org/wiki/Correlated_subquery) resulting in a full scan of the apk table for each row in the app table. This takes in the order of 25 seconds on my Moto X 2nd Gen.
This branch improves this process by doing the queries in an [sqlite in-memory database](https://sqlite.org/inmemorydb.html), with the results transferred to the database on disk when done. The time required drops from 25 seconds to ~0.5 seconds on my device.
*Note:* I was hoping this would also improve the "Processing ..." Part of the udpater, given it was inserting into an in memory table instead of on disk. If it did have any effect, it was negligible though, so that part is still likely slower than it could be. Each 50 apps (and their associated apks) takes between 150ms and 500ms on my Moto X.
*Secondary Note:* When creating the in memory database, I create indexes for some columns as per before. This technically should slow down the inserts we do, however in practice they had almost no effect. As such, I've left the index creation there because it is required for the correlated subqueries to not suck.
See merge request !269
Fixes for priv extension install
For now, disable install of privileged extension on Android >=5.1 until we found better methods.
Also, fix crash of dialogs on Android 6 using a workaround for transparent activities and some code simplifications.
See merge request !259
This way, error lines like this one:
Waiting for emulator to start: unknown: error: no devices found
Become:
Waiting for emulator to start: error: no devices found
Otherwise, we'd interpret this as "booting", which is wrong:
$ adb -e shell getprop init.svc.bootanim
* daemon not running. starting it now on port 5037 *
* daemon started successfully *
error: no devices found
This increases the speed of the complex queries required at the end
of the update process to:
* calculate suggested version codes
* figure out icon urls
* etc,
by two orders of magnitude.
This was there as a workaround for #1, but that has subsequently
been fixed. Thus, the hack is no longer required. Also removed an
additional `AND` because it is already performed in the `JOIN`.
I supsect this last one would've been eliminated by the sqlite
optimizer anyway, but the query is slightly simpler now.
This fix doesn't improve performance as much as I'd hoped, but it
is something.
Translators:
Danial Behzadi Persian
fastest noob Turkish
Fert Bálint Hungarian
Green Lunar Hebrew
Jean-Baptiste French
Karola Marky Japanese
Kristjan Räts Estonian
Licaon Kter Romanian
Marian Hanzel Slovak
Mohamad Hasan Al Banna Indonesian
naofum Japanese
Tobias Bannert German
YFdyh000 Simplified Chinese
Added cancel action to notifications.

See merge request !267
This happened to me when I clicked on an app link for a new app which
was already in the repo, but I had not ran an index update yet since the
app got built. Stack trace prior to the fix follows.
java.lang.RuntimeException: Unable to destroy activity {org.fdroid.fdroid/org.fdroid.fdroid.AppDetails}: java.lang.NullPointerException:
Attempt to invoke virtual method 'void android.support.v4.content.LocalBroadcastManager.unregisterReceiver(android.content.BroadcastReceiver)' on a null
object reference
at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:3865)
at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:3883)
at android.app.ActivityThread.-wrap5(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1417)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5461)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void
android.support.v4.content.LocalBroadcastManager.unregisterReceiver(android.content.BroadcastReceiver)' on a null object reference
at org.fdroid.fdroid.AppDetails.unregisterDownloaderReceivers(AppDetails.java:469)
at org.fdroid.fdroid.AppDetails.onDestroy(AppDetails.java:569)
at android.app.Activity.performDestroy(Activity.java:6422)
at android.app.Instrumentation.callActivityOnDestroy(Instrumentation.java:1143)
at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:3852)
... 9 more
Fixes a crash reported by ACRA:
java.lang.RuntimeException: Unable to destroy activity {org.fdroid.fdroid/org.fdroid.fdroid.AppDetails}: java.lang.NullPointerException
at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:3281)
at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:3299)
at android.app.ActivityThread.access$1200(ActivityThread.java:133)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4812)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:792)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:559)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at org.fdroid.fdroid.AppDetails.cleanUpFinishedDownload(AppDetails.java:442)
at org.fdroid.fdroid.AppDetails.onDestroy(AppDetails.java:567)
at android.app.Activity.performDestroy(Activity.java:5366)
at android.app.Instrumentation.callActivityOnDestroy(Instrumentation.java:1124)
at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:3268)
... 11 more
This used to be the case, which is why only minimal changes were
required to bring it back. This also makes it take the same files that
checkstyle does, which is more consistent.