This is the last Android code in the whole suite of Downloader subclasses,
so now we can write JUnit tests for them all, and avoid the fragility of
tests running on the emulator.
When running tests on the host machine, android.jar contains no code at all
which is totally stupid. We can keep android.util.Log in there because it
does not affect the logic at all. Then just set that android.jar to return
generic values using:
unitTests.returnDefaultValues = true
If there is no LocalBroadcastManager, then the Downloader tests can be done
with pretty plain JUnit and then do not require the Android emulator to run
Fix crash when returning to swap after cancelling
Fixes#409. The problem was that there was some listeners being added for broadcast events when the swap view was shown. These were never removed, and so cancelling swap, then returning to it would spin up a _new_ activity with new views, while the old listeners were still around. When the old listeners received events, they would try to talk to their associated `Activity`. This no longer existed, so a crash ensued.
While I was fixing the specific bug associated with #409, I took the opportunity to make more of the event listeners well behaved in the swap process. I don't think any of them were liable to cause crashes, but were likely to cause some weirdness at some point in time if they were not fixed.
*Note:* This swap view was an exercise in moving away from `Fragment`s towards an `Activity` with individual `View`s. I'm going to call this a bit of a failure at this point, because there is so much work that needs to be invested in implementing lifecycle stuff in our custom views. `Fragment`s naturally come with lifecycle methods that are familiar to other Android dev's looking to contribute to this project (even if they are a little difficult to understand at times). Implementing our own custom Views instead still results in similar classes of bugs (i.e. talking to an `Activity` when the view no longer is part of that activity).
A classic example of this is in my usage of the `onDetachedFromWindow` function in the `View`. I have no idea if this is the best place to unregister listeners or not. In a Fragment, it would be a matter of `onPause` or one of the more well defined lifecycle methods. Empirically, `onDetachedFromWindow` seems to be well behaved. The other alternative would be for the Activity to explicitly invoke a `onRemoved` type method each view when it knows it is transitioning from one state to the next. However at this point, we are then really into reimplementing `Fragment` land.
See merge request !232
Translators:
ageru French
Ajeje Brazorf Sardinian
Mohamad Hasan Al Banna Indonesian
Paresh Chouhan Hindi
YFdyh000 Simplified Chinese
YF Simplified Chinese
Pass through a known good `Context` to `translateCategories`
All the good work to make sure that `getActivity()` actually returned
a proper context, obtaining a final reference to that known good activity
object, and then using that in the background thread is thrown away.
The reason was because the `translateCategories` method would go and
call `getActivity()` all over again. This changes the `translateCategories`
helper function so that it asks for a `Context`. This way, a known
good `Context` can be passed in, rather than having to perform a check
to see if `getActivity()` is good again.
Fixes#603 (Hopefully)
See merge request !231
The old swap code used to delegate to the `AppDetails` activity when
touching an app in the swap view. Now it shows the install button
and download feedback inline. The code which used to exist is no
longer required.
This fixes the following bugs:
* `BroadcastReceiver` was never being created due to incorrect guard
condition `if (pollForUpdatesReceiver != null)` (should have been
`== null`).
* Called `unregisterReceiver` rather than `registerReceiver`.
* Even if it did work, it didn't make an effort to unregister the receiver.
In addition, the creation and listening with the `BroadcastReceiver is
now done in a way similar to the other swap views:
* Create it as a `final` member variable.
* `registerReceiver` when view is inflated.
* `unregisterReceiver` when view is detached.
Previously the receiver was added but never removed. The result
is that once a swap session is cancelled, the receiver still
gets broadcasts.
This is what was causing the bug in #409. It was trying to access
the `Activity` once it had been closed, and another swap session started
with a new activity.
All the good work to make sure that `getActivity()` actually returned
a proper context, obtaining a final reference to that known good activity
object, and then using that in the background thread is thrown away.
The reason was because the `translateCategories` method would go and
call `getActivity()` all over again. This changes the `translateCategories`
helper function so that it asks for a `Context`. This way, a known
good `Context` can be passed in, rather than having to perform a check
to see if `getActivity()` is good again.
Update Support Library components to 23.2.1
As far as I can see from the release notes, 23.2.1 does not fix any bugs that could affect F-Droid. Anyway, it's better to be up-to-date.
See merge request !228
CI: Bump docker image
Also use a specific tag instead of latest, so that pushing latest on
Docker Hub won't break older branches and tags.
See merge request !229
gitlab-ci: enable lint, log posting, and caching
Some work to improve the CI functions, and first stab at getting parts running in parallel.
See merge request !211
* splitting out the tools script allows less things to happen on the
main job, and runs the tools script in parallel, which should speed
things up.
* `gradle check` also runs lint, and anything else we might add to
that meta-target.
* `gradle build` also runs tests, `gradle assemble` does not
This stores the Android SDK tarball and gradle caches between builds
to speed things up. Since the unpacked SDK gets unpacked very time,
updating the version is just a matter of changing the variable. Since
only the gradle caches are stored, i.e. the jars and gradle binaries,
updates there will only add more files to the cache.
Code Style : Changed variable names to be consistent with other variable names
variable names are inconsistent in other files as well. At some places it is `mVariableName` and in some places it is `variableName`.
suggestion : rename all public variables to `publicVaraible` and all private variables to `mPrivateVariable` ?
we can use http://udacity.github.io/android-nanodegree-guidelines/index.html
See merge request !225
Translators:
Adrià García-Alzórriz Catalan
Adrià García-Alzórriz Spanish
Benedikt Volkmer German
Irvan Kurniawan Indonesian
Licaon Kter Romanian
Marcelo Santana Portuguese (Brazil)
Massimiliano Caniparoli Italian
Mladen Pejaković Serbian
Mohamad Hasan Al Banna Indonesian
naofum Japanese
Pander Dutch
Phạm Nguyễn Hoàng Vietnamese
riotism Chinese (Hong Kong)
Tobias Bannert German
Verdulo Esperanto
Verdulo Polish
Ensure `getContentResolver()` is not requested from `null` object.
Should fix#554, however I couldn't reproduce this. At the very least, I fail to see how it is possible with this new change for a `null` to get passed to `AppProvider.Helper.categories`, whereas it could've before.
In the process, I also made the database query run on the background thread, then update the UI on the UI thread.
See merge request !224
Previously, it was not explicit that the `onCreate` happened to be invoked
in the UI thread. Now it is, due to passing `new Handler(Looper.getMainLooper())`.
Also, the categories are now loaded in a background task, and then the UI is
updated on the UI thread.
Translators:
ageru French
Danial Behzadi Persian
enolp Asturian
ezjerry liao Chinese (Taiwan)
Fr Translation French
Hsiu-Ming Chang Chinese (Taiwan)
Jonatan Swedish
relan Russian
riotism Chinese (Hong Kong)