Skip to content

Restartables examples

inorichi edited this page Jan 14, 2016 · 1 revision

In the current version (2.0.4) there are 3 delivery methods. They are explained in the documentation:

  • deliverLatestCache keeps the latest onNext value and emits it each time a new view gets attached. If a new onNext value appears while a view is attached, it will be delivered immediately.

  • deliverFirst delivers only the first onNext value that has been emitted by the source observable.

  • deliverReplay keeps all onNext values and emits them each time a new view gets attached. If a new onNext value appears while a view is attached, it will be delivered immediately.

NOTE: All the examples from this page use lambdas. You should strongly consider adding retrolambda to your project to avoid writing lots and lots of anonymous classes.

Basic example

This example will fetch items from the network when the presenter is created.

public class MainPresenter extends RxPresenter<MainActivity> {

    private static final int REQUEST_ITEMS = 1;

    @Override
    protected void onCreate(Bundle savedState) {
        super.onCreate(savedState);

        restartableLatestCache(REQUEST_ITEMS,
                () -> App.getServerAPI()
                    .getItems()
                    .observeOn(AndroidSchedulers.mainThread()),
                (activity, response) -> activity.onItems(response.items),
                (activity, throwable) -> activity.onItemsError(throwable));

        // After a process restart, it will restart itself when registering the restartable
        if (savedState == null)
            start(REQUEST_ITEMS);
    }

}

Example sending parameters from the view

You may need to send a parameter for a network request from the view. This example does so.

You will only have to call getPresenter().request("my_parameter") from the view.

public class MainPresenter extends RxPresenter<MainActivity> {

    private static final int REQUEST_ITEMS = 1;

    private static final String NAME_KEY = MainPresenter.class.getName() + "#name";

    private String name;

    @Override
    protected void onCreate(Bundle savedState) {
        super.onCreate(savedState);

        // Recover the value after a process restart, you have to restore it before
        // registering the restartable, or you will get a NullPointerException
        if (savedState != null)
            name = savedState.getString(NAME_KEY);

        restartableLatestCache(REQUEST_ITEMS,
                () -> App.getServerAPI()
                    .getItems(name)
                    .observeOn(AndroidSchedulers.mainThread()),
                (activity, response) -> activity.onItems(response.items),
                (activity, throwable) -> activity.onItemsError(throwable));
    }

    @Override
    protected void onSave(@NonNull Bundle state) {
        super.onSave(state);
        state.putString(NAME_KEY, name);
    }

    public void request(String name) {
        this.name = name;
        start(REQUEST_ITEMS);
    }
}

And an example activity:

@RequiresPresenter(MainPresenter.class)
public class MainActivity extends NucleusActivity<MainPresenter> {

    ArrayAdapter<Item> adapter;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // View and adapter initialization
        // ...

        if (savedInstanceState == null)
            requestItems("initial query");
    }

    public void onItems(List<Item> items) {
        adapter.clear();
        adapter.addAll(items);
    }

    public void onItemsError(Throwable throwable) {
        Toast.makeText(this, throwable.getMessage(), Toast.LENGTH_LONG).show();
    }

    // You can use this method to (re)start the restartable with a new parameter
    private void requestItems(String query) {
        getPresenter().request(query);
    }
}

Example sending parameters from the view (with Icepick)

To avoid manually saving/restoring instances every time, you can add Icepick to your project and create a class BasePresenter.

public class BasePresenter<V extends ViewWithPresenter> extends RxPresenter<V> {

    @Override
    protected void onCreate(Bundle savedState) {
        super.onCreate(savedState);
        Icepick.restoreInstanceState(this, savedState);
    }

    @Override
    protected void onSave(@NonNull Bundle state) {
        super.onSave(state);
        Icepick.saveInstanceState(this, state);
    }

}

If you extend from BasePresenter, your presenter would look like this:

import icepick.State;

public class MainPresenter extends BasePresenter<MainActivity> {

    private static final int REQUEST_ITEMS = 1;

    @State String name;

    @Override
    protected void onCreate(Bundle savedState) {
        super.onCreate(savedState);

        restartableLatestCache(REQUEST_ITEMS,
                () -> App.getServerAPI()
                    .getItems(name)
                    .observeOn(AndroidSchedulers.mainThread()),
                (activity, response) -> activity.onItems(response.items),
                (activity, throwable) -> activity.onItemsError(throwable));
    }

    public void request(String name) {
        this.name = name;
        start(REQUEST_ITEMS);
    }
}