Put null check around access of `R.id.header` fragment.
Please note I haven't reproduced the specific problem. Also, the stack
traces being reported are only marginally informative, because they are
in response to a content providers firing events, and thus don't have
any context about when or where the event was fired from.
However, my looking at the code seems to indicate that this will prevent
NPE when the Activity is no longer visible but an app is finished
installing. Also, the view should still update correctly on resuming the
Activity because the `onResumeFragments()` methods will be invoked
which invokes the `refreshHeaders()` method.
Fixes#286.
See merge request !202
Please note I haven't reproduced the specific problem. Also, the stack
traces being reported are only marginally informative, because they are
in response to a content providers firing events, and thus don't have
any context about when or where the event was fired from.
However, my looking at the code seems to indicate that this will prevent
NPE when the Activity is no longer visible but an app is finished
installing. Also, the view should still update correctly on resuming the
Activity because the `onResumeFragments()` methods will be invoked
which invokes the `refreshHeaders()` method.
Fixes#286.
Add ReactiveX (rxjava + rxandroid) as dependency
This is going to be used to make the managing of async tasks in F-Droid easier to reason about. It does this by using a more functional style to performing multiple different asynchronous tasks as compared to the Android `AsyncTask` or `Service` or some other approach.
More specifically, I have some changes coming that will use this dependency.
I wanted to merge this separately so that it doesn't matter which of the changes I'm working on gets merged first.
I've never added a `dependencyVerification` to the gradle build before, and there wasn't a whole bunch of docs on the interwebs about how to do that. So I did a SHA256 sum of some other .jar files in my gradle cache and compared them to the existing dependency verification settings and they did match. So I also did a SHA256 sum of the newly added dependencies and gradle seems happy with the hashes I've chosen.
See merge request !197
This is going to be used to make the managing of async tasks in
F-Droid easier to reason about. It does this by using a more
functional style to performing multiple different asynchronous tasks
as compared to the Android `AsyncTask` or `Service` or some other approach.
fix AOSP build integration
The build isn't done from the top-level directory so the symlink needs
to use an absolute path.
Fixes#551.
See merge request !200
Fix 560 (searching only whitespace)
When no keywords to search, use an empty query selection that evaluates to "1".
This means that instead of building invalid SQL such as `WHERE (() OR ())` it
will build `WHERE((1) OR (1))` which, while non-optimal, is at least valid.
In fact, I'm not even sure that it is non optimal because I'd hope the sqlite
query optimizer is able to realise that `1 OR 1` is effectively a no-op.
Fixes issue #560.
See merge request !201
Changing the search query is quite an expensive operation, so this does some rudimentary
checking to see if the two queries are meaningfully different. At present, it trims the
strings and does a case insensitive comparison.
The query is eventually exploded based on whitespace, so leading and trailing white
space is not important. Also, sqlite `LIKE` clauses are case insensitive, so case
is unimportant. Having said that, I'm not sure how someone will be able to change
the queries case without first deleting and then adding characters (thus inducing
meaningfull changse).
This means that instead of building invalid SQL such as `WHERE (() OR ())` it
will build `WHERE((1) OR (1))` which, while non-optimal, is at least valid.
Fixes issue #560.
Its use was removed long ago, and the dependency was left behind for
some reason. This commit can be reverted if it's needed in the future
again.
This of course slightly simplifies the build thus speeding it a little,
but what's more interesting is that the output apk is also ~100KB
smaller. So something is going on.
Translators:
bd339 Danish
Danial Behzadi Persian
David Koňařík Czech
Massimiliano Caniparoli Italian
Olexandr Nesterenko Ukrainian
Sebastiano Pistore Italian
Tobias Bannert German
Tong Hui Chinese (China)
As reported by a user via ACRA:
java.util.UnknownFormatConversionException: Conversion: I
at java.util.Formatter$FormatToken.unknownFormatConversionException(Formatter.java:1399)
at java.util.Formatter$FormatToken.checkFlags(Formatter.java:1336)
at java.util.Formatter.transform(Formatter.java:1442)
at java.util.Formatter.doFormat(Formatter.java:1081)
at java.util.Formatter.format(Formatter.java:1042)
at java.util.Formatter.format(Formatter.java:1011)
at java.lang.String.format(String.java:1988)
at android.content.res.Resources.getString(Resources.java:355)
at android.content.Context.getString(Context.java:350)
at org.fdroid.fdroid.UpdateService$1.onReceive(UpdateService.java:210)
at android.support.v4.content.LocalBroadcastManager.executePendingBroadcasts(LocalBroadcastManager.java:297)
at android.support.v4.content.LocalBroadcastManager.access$000(LocalBroadcastManager.java:46)
at android.support.v4.content.LocalBroadcastManager$1.handleMessage(LocalBroadcastManager.java:116)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5136)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:740)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:556)
at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:132)
at dalvik.system.NativeStart.main(Native Method)
Fix 265 database locked crash (I'm pretty sure)
Previously, all of the various subclasses of FDroidProvider would create
their own database open helper in their respective `onCreate()` methods.
This seemed to be the cause of the multiple database locked exceptions.
Various online articles/SO posts/etc helped come to this conclusion:
* http://stackoverflow.com/a/3689883
* http://stackoverflow.com/a/8888606
* https://web.archive.org/web/20150709074733/http://www.dmytrodanylyk.com/pages/blog/concurrent-database.html
This should fix#265.
In the process, also did away with the two `read()` and `write()` methods
that returned a "readable" and "writeable" database respectively. It turns
out that it doesn't quite do what I originally thought. There is not much
benefit to specifying to the database helper that you want a readable/writeable
database. In fact, it is often the case that a call to `read()` would most
likely have returned the same instance that is returned by `write()`. The
semantics of them were therefore broken, and they've been replaced with
`db()`.
See merge request !196
The fix for the database locking bug was to have a singleton
`DBHelper` instance. This breaks tests because multiple tests
share the same database. The solution is to:
* Hack together a static method which clears the singleton,
then invoke it in the `setUp()` method for relevant test cases.
* Ensure the mock context provided to the providers during
the tests is able to provide a context via `getApplicationContext()`.
Without this, the mock context throws an `UnsupportedOperationException`
when invoking this method.
Using whatever `Activity` as the `Context` used to construct the first content
provider means that it will be help onto in memory until the application is GC'ed.
Previously, all of the various subclasses of FDroidProvider would create
their own database open helper in their respective `onCreate()` methods.
This seemed to be the cause of the multiple database locked exceptions.
Various online articles/SO posts/etc helped come to this conclusion:
* http://stackoverflow.com/a/3689883
* http://stackoverflow.com/a/8888606
* https://web.archive.org/web/20150709074733/http://www.dmytrodanylyk.com/pages/blog/concurrent-database.html
This should fix#265.
In the process, also did away with the two `read()` and `write()` methods
that returned a "readable" and "writeable" database respectively. It turns
out that it doesn't quite do what I originally thought. There is not much
benefit to specifying to the database helper that you want a readable/writeable
database. In fact, it is often the case that a call to `read()` would most
likely have returned the same instance that is returned by `write()`. The
semantics of them were therefore broken, and they've been replaced with
`db()`.
Finish main activity after navigating to AppDetails activity.
This is what used to happen before the recent refactor to the search UI.
Finishing the main activity means that it never comes back to handle the
"View this app" intent again. Instead, the main Activity just becomes an
entry point for redirecting the UI to the correct place.
Incidentally, I don't particularly like the current solution even though
it should work, and hope to come up with a better one in the future. The
reason is because the behaviour of some methods (`onCreate()` +
`handleIntent()`) is what defines the behaviour of other methods
(`checkForAddRepoIntent()`). This means it is hard to reason about the
state of the activity at any point in time. Developers need to be careful
when making changes to the `onCreate()` method because modifying it has
unintended consequences. That is what caused the problem in issue #541.
Fixes#541.
See merge request !195
This is what used to happen before the recent refactor to the search UI.
Finishing the main activity means that it never comes back to handle the
"View this app" intent again. Instead, the main Activity just becomes an
entry point for redirecting the UI to the correct place.
Incidentally, I don't particularly like the current solution even though
it should work, and hope to come up with a better one in the future. The
reason is because the behaviour of some methods (`onCreate()` +
`handleIntent()`) is what defines the behaviour of other methods
(`checkForAddRepoIntent()`). This means it is hard to reason about the
state of the activity at any point in time. Developers need to be careful
when making changes to the `onCreate()` method because modifying it has
unintended consequences. That is what caused the problem in issue #541.
Fixes#541.
Translators:
Adam Magnier French
Adrià García-Alzórriz Catalan
Adrià García-Alzórriz Spanish
Ajeje Brazorf Sardinian
Alberto Moshpirit Spanish
Dominik george French
Dominik george German
Enol Puente Asturian
Jean-Baptiste French
M2ck French
Marcelo Santana Portuguese (Brazil)
Massimiliano Caniparoli Italian
Mladen Pejaković Serbian
Nam Mai Hoang Vietnamese
naofum Japanese
Nick Bishop Greek
riotism Chinese (Hong Kong)
Sérgio Marques Portuguese (Portugal)
tacsipacsi Hungarian
ultrapeer Turkish
Андрій Бандура Ukrainian
Дмитрий Михирев Russian
Handle fdroidrepos:// urls better.
Before, it only handled the incoming `Intent` in `onResume()`. Now, it happens in `onNewIntent()` too (but ensures to only handle the same intent once).
Note the `onResume()` only ever handles the original intent, not the new intent. See inline comments for why.
Fixes#524.
See merge request !192
Before, both the swap activity and the fdroid activity would use
the "handled" key to check if an intent had been handled. This caused
problems, because by the time we got to handling the add repo intent,
it had already been "handled" by the swap activity so we bailed.
Before, it only happened in onResume(). Now, it happens in onNewIntent()
too (but ensures to only handle the same intent once).
Note the onResume() only ever handles the original intent, not the new
intent.
Fixes#524.