<commit_before>
# Retrofit and the CallProcessor

The [CallProcessor](https://github.com/erdo/android-fore/blob/master/fore-retrofit/src/main/java/co/early/fore/retrofit/CallProcessor.java) is a wrapper for the Retrofit2 Call class. For a usage example, please see the [Retrofit Example App Source Code](/android-fore/#fore-4-retrofit-example). The CallProcessor allows us to abstract all the networking related work so that the models can just deal with either successful data or domain model error messages depending on the result of the network call (the models don't need to know anything about HTTP codes or io exceptions etc).

When taking advantage of Java lambda expressions or in Kotlin, the code can become very tight indeed:


<!-- Tabbed code sample -->
 <div class="tab">
   <button class="tablinks java" onclick="openLanguage('java')">Java</button>
   <button class="tablinks kotlin" onclick="openLanguage('kotlin')">Kotlin</button>
 </div>

<pre class="tabcontent tabbed java"><code>
callProcessor.processCall(service.getFruits("3s"), workMode,
    successResponse -> handleSuccess(successResponse),
    failureMessage -> handleFailure(failureMessage)
);
 </code></pre>

<pre class="tabcontent tabbed kotlin"><code>
callProcessor.processCall(service.getFruits("3s"), workMode,
    { successResponse -> handleSuccess(successResponse) },
    { failureMessage -> handleFailure(failureMessage) }
)
 </code></pre>


## Custom APIs

All APIs will be slightly different regarding what global headers they require, what HTTP response code they return and under what circumstances and how these codes map to domain model states. There will be a certain amount of customisation required, see the sample retrofit app for an [example](https://github.com/erdo/android-fore/tree/master/example04retrofit/src/main/java/foo/bar/example/foreretrofit/api) of this customisation.

The sample apps all use JSON over HTTP, but there is no reason you can't use something like protobuf, for example.


## Testing Networking Code

Another advantage of using the CallProcessor is that it can be mocked out during tests. The fore-retrofit sample app takes two alternative approaches to testing:

- [one](https://github.com/erdo/android-fore/blob/master/example04retrofit/src/test/java/foo/bar/example/foreretrofit/feature/fruit/FruitFetcherUnitTest.java) is to simply mock the callProcessor so that it returns successes or failures to the model
- [the other](https://github.com/erdo/android-fore/blob/master/example04retrofit/src/test/java/foo/bar/example/foreretrofit/feature/fruit/FruitFetcherIntegrationTest.java) is to use canned HTTP responses (local json data, and faked HTTP codes) to drive the call processor and therefore the model.

As with testing any asynchronous code with **fore**, we use WorkMode.**SYNCHRONOUS** to cause the Call to be processed on one thread which simplifies our test code (no need for latches etc).



# Adapters notifyDataSetChangedAuto()

*For a clean implementation in a small sample app, please see the [Adapter Example App Source Code](/android-fore/#fore-3-adapter-example)*

Ahh adapters, I miss the good old days when all you had to do was call notifyDataSetChanged(). And the best place to call it is from inside the syncView() method:

<!-- Tabbed code sample -->
 <div class="tab">
   <button class="tablinks java" onclick="openLanguage('java')">Java</button>
   <button class="tablinks kotlin" onclick="openLanguage('kotlin')">Kotlin</button>
 </div>

<pre class="tabcontent tabbed java"><code>
public void syncView() {

  // set enabled states and visibilities etc
  ...

  adapter.notifyDataSetChanged();
}
 </code></pre>

<pre class="tabcontent tabbed kotlin"><code>
fun syncView() {

  // set enabled states and visibilities etc
  ...

  adapter.notifyDataSetChanged()
}
 </code></pre>


In this way you let your adapters piggy back on the observer which you have already setup for your view (it's the observer that calls syncView() whenever the model changes).

You could also add your adapter as an observer on the model directly, but doing it like that usually causes problems because you will also need to find a way to remove it correctly (see these items in the code review check list [here](https://erdo.github.io/android-fore/05-extras.html#non-lifecycle-observers) and [here](https://erdo.github.io/android-fore/05-extras.html#add-remove)).

If you're not overly concerned with list animations I would continue to call notifyDataSetChanged anyway (yes it is marked as deprecated, but the alternative methods that android is offering are so difficult to implement correctly that I strongly suspect they will never be able to remove the original adapter.notifyDataSetChanged() method from the API).

*By the way, I've noticed people bizarrely claiming that notifyDataSetChanged() is "inefficient" but then replacing it with code that calls DiffUtil. Nothing wrong with DiffUtil, but that's like choosing black tea instead of a latte because you're on a diet, but then taking your tea and adding whipped cream with marsh mallows on top. If you ever see a lag using notifyDataSetChanged() then you're probably doing something wrong (like re-inflating your cells' layout when you shouldn't)*


## RecyclerView Animations

So onwards and upwards! if you want list animations on android, they make you work quite hard for it. In order to get animations, you need to tell the adapter what kind of change actually happened, what rows were added or removed etc.

Happily by using the ChangeAware\* classes found in the fore-adapters library you can get **fore** to do most of the work for you.

As the name implies, the ChangeAware\*Lists are aware of how they have been changed and they feed that information back to the ChangeAwareAdapter (for your own code, just extend ChangeAwareAdapter instead of RecyclerView.Adapter).

When you call notifyDataSetChangedAuto() on the ChangeAwareAdapter, it will take care of calling the correct Android notify* method for you. The only thing you need to take care of is telling the list what happened when an item has *changed* (the list has no way of detecting that automatically itself). For that, you use the method **ChangeAware\*List.makeAwareOfDataChange(int index)** whenever an item is changed (rather than added or removed).


<!-- Tabbed code sample -->
 <div class="tab">
   <button class="tablinks java" onclick="openLanguage('java')">Java</button>
   <button class="tablinks kotlin" onclick="openLanguage('kotlin')">Kotlin</button>
 </div>

<pre class="tabcontent tabbed java"><code>
public void syncView() {

  // set enabled states and visibilities etc
  ...

  adapter.notifyDataSetChangedAuto();
}
 </code></pre>

<pre class="tabcontent tabbed kotlin"><code>
fun syncView() {

  // set enabled states and visibilities etc
  ...

  adapter.notifyDataSetChangedAuto()
}
 </code></pre>


See [here](https://github.com/erdo/android-fore/blob/master/example03adapters/src/main/java/foo/bar/example/foreadapters/ui/playlist/advanced/PlaylistAdapterAdvanced.java) for an example adapter, the list for which is held in [this](https://github.com/erdo/android-fore/blob/master/example03adapters/src/main/java/foo/bar/example/foreadapters/feature/playlist/PlaylistAdvancedModel.java) model, see if you can spot the occasional call to makeAwareOfDataChange() in the model code. This radically simplifies any [view code](https://github.com/erdo/android-fore/blob/master/example03adapters/src/main/java/foo/bar/example/foreadapters/ui/playlist/PlaylistsView.java) that needs to use an adapter and wants recycler view animations, the only thing that it needs to do is call **notifyDataSetChangedAuto()** from the **syncView()** method, rather than **notifyDataSetChanged()**.

> "the only thing a view needs to do is call **notifyDataSetChangedAuto()** from the **syncView()** method, rather than **notifyDataSetChanged()**."

## Database driven RecyclerView Animations

For lists that are being driven by a database table, the only way we can get animated changes is by comparing the two lists (the new versus the old) and try to work out what changed. This is because the view layer will not be aware of how the list has been changed as it will often be changed in another part of the system at the database layer. Thankfully Android has a *DiffUtil* class that does that for us, however it's a more heavy weight approach and isn't really useful once your lists gets larger than about 1000 items - in any case you want to be calculating the DiffResult in a separate thread.<commit_msg>doc updates<commit_after>
# Retrofit and the CallProcessor

The [CallProcessor](https://github.com/erdo/android-fore/blob/master/fore-retrofit/src/main/java/co/early/fore/retrofit/CallProcessor.java) is a wrapper for the Retrofit2 Call class. For a usage example, please see the [Retrofit Example App Source Code](/android-fore/#fore-4-retrofit-example). The CallProcessor allows us to abstract all the networking related work so that the models can just deal with either successful data or domain model error messages depending on the result of the network call (the models don't need to know anything about HTTP codes or io exceptions etc).

When taking advantage of Java lambda expressions or in Kotlin, the code can become very tight indeed:


<!-- Tabbed code sample -->
 <div class="tab">
   <button class="tablinks java" onclick="openLanguage('java')">Java</button>
   <button class="tablinks kotlin" onclick="openLanguage('kotlin')">Kotlin</button>
 </div>

<pre class="tabcontent tabbed java"><code>
callProcessor.processCall(service.getFruits("3s"), workMode,
    successResponse -> handleSuccess(successResponse),
    failureMessage -> handleFailure(failureMessage)
);
 </code></pre>

<pre class="tabcontent tabbed kotlin"><code>
callProcessor.processCall(service.getFruits("3s"), workMode,
    { successResponse -> handleSuccess(successResponse) },
    { failureMessage -> handleFailure(failureMessage) }
)
 </code></pre>


## Custom APIs

All APIs will be slightly different regarding what global headers they require, what HTTP response code they return and under what circumstances and how these codes map to domain model states. There will be a certain amount of customisation required, see the sample retrofit app for an [example](https://github.com/erdo/android-fore/tree/master/example04retrofit/src/main/java/foo/bar/example/foreretrofit/api) of this customisation.

The sample apps all use JSON over HTTP, but there is no reason you can't use something like protobuf, for example.


## Testing Networking Code

Another advantage of using the CallProcessor is that it can be mocked out during tests. The fore-retrofit sample app takes two alternative approaches to testing:

- [one](https://github.com/erdo/android-fore/blob/master/example04retrofit/src/test/java/foo/bar/example/foreretrofit/feature/fruit/FruitFetcherUnitTest.java) is to simply mock the callProcessor so that it returns successes or failures to the model
- [the other](https://github.com/erdo/android-fore/blob/master/example04retrofit/src/test/java/foo/bar/example/foreretrofit/feature/fruit/FruitFetcherIntegrationTest.java) is to use canned HTTP responses (local json data, and faked HTTP codes) to drive the call processor and therefore the model.

As with testing any asynchronous code with **fore**, we use WorkMode.**SYNCHRONOUS** to cause the Call to be processed on one thread which simplifies our test code (no need for latches etc).



# Adapters notifyDataSetChangedAuto()

*For a clean implementation in a small sample app, please see the [Adapter Example App Source Code](/android-fore/#fore-3-adapter-example)*

Ahh adapters, I miss the good old days when all you had to do was call notifyDataSetChanged(). And the best place to call it is from inside the syncView() method:

<!-- Tabbed code sample -->
 <div class="tab">
   <button class="tablinks java" onclick="openLanguage('java')">Java</button>
   <button class="tablinks kotlin" onclick="openLanguage('kotlin')">Kotlin</button>
 </div>

<pre class="tabcontent tabbed java"><code>
public void syncView() {

  // set enabled states and visibilities etc
  ...

  adapter.notifyDataSetChanged();
}
 </code></pre>

<pre class="tabcontent tabbed kotlin"><code>
fun syncView() {

  // set enabled states and visibilities etc
  ...

  adapter.notifyDataSetChanged()
}
 </code></pre>


In this way you let your adapters piggy back on the observer which you have already setup for your view (it's the observer that calls syncView() whenever the model changes).

You could also add your adapter as an observer on the model directly, but doing it like that usually causes problems because you will also need to find a way to remove it correctly (see these items in the code review check list [here](https://erdo.github.io/android-fore/05-extras.html#non-lifecycle-observers) and [here](https://erdo.github.io/android-fore/05-extras.html#add-remove)).

If you're not overly concerned with list animations I would continue to call notifyDataSetChanged anyway (yes it is marked as deprecated, but the alternative methods that android is offering are so difficult to implement correctly that I strongly suspect they will never be able to remove the original adapter.notifyDataSetChanged() method from the API).

*By the way, I've noticed people bizarrely claiming that notifyDataSetChanged() is "inefficient" but then replacing it with code that calls DiffUtil. Nothing wrong with DiffUtil, but that's like choosing black tea instead of a latte because you're on a diet, but then taking your tea and adding whipped cream with marsh mallows on top. If you ever see a lag using notifyDataSetChanged() then you're probably doing something wrong (like re-inflating your cells' layout when you shouldn't)*


## RecyclerView Animations

So onwards and upwards! if you want list animations on android, they make you work quite hard for it. In order to get animations, you need to tell the adapter what kind of change actually happened, what rows were added or removed etc.

Happily by using the ChangeAware\* classes found in the fore-adapters library you can get **fore** to do most of the work for you.

As the name implies, the ChangeAware\*Lists are aware of how they have been changed and they feed that information back to the ChangeAwareAdapter (for your own code, just extend ChangeAwareAdapter instead of RecyclerView.Adapter).

When you call notifyDataSetChangedAuto() on the ChangeAwareAdapter, it will take care of calling the correct Android notify* method for you. The only thing you need to take care of is telling the list what happened when an item has *changed* (the list has no way of detecting that automatically itself). For that, you use the method **ChangeAware\*List.makeAwareOfDataChange(int index)** whenever an item is changed (rather than added or removed).


<!-- Tabbed code sample -->
 <div class="tab">
   <button class="tablinks java" onclick="openLanguage('java')">Java</button>
   <button class="tablinks kotlin" onclick="openLanguage('kotlin')">Kotlin</button>
 </div>

<pre class="tabcontent tabbed java"><code>
public void syncView() {

  // set enabled states and visibilities etc
  ...

  adapter.notifyDataSetChangedAuto();
}
 </code></pre>

<pre class="tabcontent tabbed kotlin"><code>
fun syncView() {

  // set enabled states and visibilities etc
  ...

  adapter.notifyDataSetChangedAuto()
}
 </code></pre>


See [here](https://github.com/erdo/android-fore/blob/master/example03adapters/src/main/java/foo/bar/example/foreadapters/ui/playlist/advanced/PlaylistAdapterAdvanced.java) for an example adapter, the list for which is held in [this](https://github.com/erdo/android-fore/blob/master/example03adapters/src/main/java/foo/bar/example/foreadapters/feature/playlist/PlaylistAdvancedModel.java) model, see if you can spot the occasional call to makeAwareOfDataChange() in the model code.

This radically simplifies any [view code](https://github.com/erdo/android-fore/blob/master/example03adapters/src/main/java/foo/bar/example/foreadapters/ui/playlist/PlaylistsView.java) that needs to use an adapter and wants recycler view animations, the only thing that it needs to do is call **notifyDataSetChangedAuto()** from the **syncView()** method, rather than **notifyDataSetChanged()**.

> "just call **notifyDataSetChangedAuto()** from the **syncView()** method, rather than **notifyDataSetChanged()**."

## Database driven RecyclerView Animations

For lists that are being driven by a database table, the only way we can get animated changes is by comparing the two lists (the new versus the old) and try to work out what changed. This is because the view layer will not be aware of how the list has been changed as it will often be changed in another part of the system at the database layer. Thankfully Android has a *DiffUtil* class that does that for us, however it's a more heavy weight approach and isn't really useful once your lists gets larger than about 1000 items - in any case you want to be calculating the DiffResult in a separate thread.
{'fraction_non_alphanumeric': 0.08687518269511839, 'fraction_numerical': 0.0029231218941829875, 'mean_word_length': 4.908808290155441, 'pattern_counts': {'":': 0, '<': 93, '<?xml version=': 0, '>': 103, 'https://': 18, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '617210', 'n_tokens_mistral': 4599, 'n_tokens_neox': 4460, 'n_words': 2016}