Deprecated: early StackOverflow discussions said you need a Service for network tasks. Actually, you need just a ViewModel/Presenter which outlives a View.
Decoupled executor — the easiest & type-safe way to run code in Android service
In many cases you can use presenters which survive lifecycle changes, like in Moxy.
This library is abandoned and deprecated.
compile 'net.aquadc.decouplex:decouplex:0.0.3'
compile 'net.aquadc.decouplex:decouplexRetrofit:0.0.3'
compile 'net.aquadc.decouplex:decouplexRetrofit:0.0.3:release@aar'
— this strange thing will be fixed in next release
- Add something like
@OnFinish
withfinally
semantics; - Support DecouplexBatchRequest.retry & document DecouplexBatch;
- Develop
REMOTE
DeliveryStrategy
to use implementation that runs in another process; - Static factory with default parameter values to use in Kotlin without Builder;
- Eager validation;
- less ProGuard rules.
- Support nullable
@OnResult
and@OnError
methods' arguments by means of@DcxNullable
annotation; - Allow some methods to be called without result or error delivery by means of
@DcxDelivery
annotation; - If an exception has raised in
@OnResult
method, deliveringInvocationTargetException
to@OnError
; - If an exception has raised in
@OnError
method, delivering two exception to fallback handler.
Now it's OK for @OnResult
and @OnError
methods to declare (throws
) and throw exceptions —
you can catch them all inside your fallback error handler and send them to Crashlytics.
- DeliveryStrategy: a way to transfer arguments from UI to Service.
The only one is available for now —
DeliveryStrategies.LOCAL
. Method arguments and return value will now be transferred out of Bundle and there's no need for them to be Parcelable; - Adapters' API changed: they aren't dependent on Bundle any more;
- A bug that caused a crash on SocketTimeoutException delivery was fixed (actually, any exception delivery would be failed if this exception provides no message but @OnError method requires it).
- Arguments and return values delivery;
- Wildcard result/error handlers (e. g. @OnResult("list*") works with all methods which names start with "list");
@Debounce(delay)
.
You can write your code like this:
class SampleFragment extends DecouplexFragment {
private GitHubService gitHubService;
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (gitHubService == null) {
// configure Retrofit
GitHubService gitHubRetrofitService =
new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.addConverterFactory(JacksonConverterFactory.create())
.build()
.create(GitHubService.class);
// configure Decouplex
gitHubService = DecouplexBuilder
.retrofit2(getActivity(),
GitHubService.class, gitHubRetrofitService, getClass());
}
}
// OnClick
public void myGitHub() {
enableUi(false);
gitHubService.listRepos("Miha-x64");
}
@OnResult("listRepos")
protected void onReposListed(List<Repo> repos) {
resultView.setText(formatRepos(repos));
enableUi(true);
}
// some code
// setting OnClickListeners
// enableUi & formatRepos methods
// and other presenter logic
}
Of course, GitHubService in this example is a Retrofit2-compatible interface:
public interface GitHubService {
@GET("users/{user}/repos")
Call<List<Repo>> listRepos(@Path("user") String user);
}
You have to add service in manifest:
<service android:name="net.aquadc.decouplex.DecouplexService" />
When your class does not extend DecouplexActivity or DecouplexFragment, you can register & unregister BroadcastReceiver wherever you need: in onCreate/onDestroy, onStart/onStop, or onResume/onPause.
class MyClass extends Fragment or Activity {
private DecouplexReceiver decouplexReceiver;
@Override
protected void onStart() {
super.onStart();
if (decouplexReceiver == null)
decouplexReceiver = new DecouplexReceiver(this);
decouplexReceiver.register();
}
@Override
protected void onStop() {
decouplexReceiver.unregister();
super.onStop();
}
}