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
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.
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
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)
Translators:
Adrià García-Alzórriz Catalan
Adrià García-Alzórriz Spanish
Ajeje Brazorf Sardinian
Alberto Moshpirit Spanish
Alex Kalles Greek
jetamkadlec Czech
Ldm Public French
Licaon Kter Romanian
Mladen Pejaković Serbian
naofum Japanese
Olexandr Nesterenko Ukrainian
Verdulo Esperanto
Verdulo Polish
Previously, they were registered, then forgotten. This means that each time
the start swap view was run, another receiver was registered. As a result,
they were being invoked multiple times.
It doesn't appear that this had any specific side effects which were terrible,
but they definitely have the potential to going forward.
Note that because we are not using `Fragments` with their convoluted, but at
least well documented API, I'm not 100% certain that I've unregistered the
receivers at the right location.
Previously, something like this would happen:
* Swap service is cancelled
* WiFi swap is asked to stop
* Event is broadcast when done
* UI listens to this event
* Upon receiving the event, it updates the UI
* Updating the UI triggers an event, causing the process to happen again
An alternative solution to this would have been for the UI to stop listening
to listeners before WiFi swap is shut down, but that is then only specific
to the case when the swap view is being destroyed/removed. This could also
happen in other situations however, such as when the swap service times out.
When the view is detached, then the listeners will be unregistered.
This will also help in the future so that they can be temporarily
unregistered when manually changing the state of the switches.