Jetpack c’est quoi ?

Un ensemble de librairies et bonnes pratiques pour le développement Android:

Toute la documentation se trouve ici : https://developer.android.com/jetpack

Foundation

Les grosses briques de base pour le développement

Architecture

Beaucoup de choses ici, voyons déjà ensemble les patterns de développement préconisés.

MVC

A la fois le plus basique et classique mais dur à cerner.

Pattern MVC

Juste une combinaison de patterns. Les reconnaissez-vous ?

MVC

A la fois le plus basique et classique mais dur à cerner.

Pattern MVC

MVP

Comparaison MVC / MVP

Comparaison MVC/MVP

MVVM

Parce qu’on n’en avait encore pas assez avec MVC et MVP…

Le ViewModel a pour vocation à faire le pont entre les données du modèle et leur présentation dans la vue. En général il est composé de deux choses :

ViewModel

public class ReposViewModel extends ViewModel {
    private MutableLiveData<List<Repo>> repos;
    public LiveData<List<Repo>> getRepos() {
        if (repos == null) {
            repos = new MutableLiveData<>();
            loadRepos();
        }
        return repos;
    }
    private void loadRepos() {
        // Appel asynchrone pour charger les repos
    }
}

ViewModel (instanciation)

public class ReposActivity extends AppCompatActivity {
    public void onCreate(Bundle savedInstanceState) {
        // Si ce ViewModel n'a jamais été instancié, on le créée
        // Sinon on le récupère dans le ViewModelProvider
        ReposViewModel model =
                ViewModelProviders.of(this).get(ReposViewModel.class);
        model.getRepos().observe(this, repos -> {
            // On met à jour l'UI ici
        });
    }
}
Caution Le ViewModel ne doit jamais avoir de lien vers la vue (sinon leak)

LiveData

Vous avez sûrement remarqué l’utilisation de la classe LiveData dans l’exemple précédent. C’est l'équivalent (en moins puissant) des observables RxJava.

On peut observer (avec la méthode observe) les valeurs émises (avec value ou postValue)

Data Binding library

Liaison directe de données dans le XML.

Très souvent utilisé conjointement avec un ViewModel.

Il faut pour cela faire plusieurs choses.

Data Binding (build.gradle)

On déclare que notre application utilise du data binding.

android {
    ...
    dataBinding {
        enabled = true
    }
}

Data Binding (layout)

On définit les données injectées dans le layout.

<layout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto">
    <data>
        <variable
            name="viewmodel"
            type="com.myapp.data.ViewModel" />
    </data>
    <ConstraintLayout... /> <!-- UI layout's root element -->
</layout>

Data Binding (layout)

On les appelle depuis l’intérieur du layout.

<TextView android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@{user.firstName, default=my_default}"/>

Data Binding (Activity)

Il faut qu’on injecte dans notre layout les éléments en question.

class ViewModelActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // On instancie le ViewModel
        UserModel userModel = ViewModelProviders.of(getActivity())
                                                  .get(UserModel.class);
        // Inflate de la vue et récupération de la classe de binding
        UserBinding binding =
                DataBindingUtil.setContentView(this, R.layout.user);
        // On renseigne la propriété de la classe de binding
        binding.viewmodel = userModel;
    }
}

Data Binding (extras)

Les Binding Adapters permettent de définir de nouvelles propriétés sur vos classes bindées.

@BindingAdapter("app:goneUnless")
public static void goneUnless(View view, Boolean visible) {
    view.visibility = visible ? View.VISIBLE : View.GONE;
}

Room

Une base de données moderne, avec support des LiveData.

On va aller jeter un oeil au code ça ira plus vite !

En composant tout, offline-first

Room flow