-
Notifications
You must be signed in to change notification settings - Fork 16
How to use Chronos
There are four steps you should take to fully integrate Chronos to your app.
First of all, you need setup your Activity or Fragment to be connected to Chronos. There are two ways:
- You may create a field of ChronosConnector type in your Activity of Fragment, and use its interface to do the job. It is important to call its
onCreate, onResume, onSaveInstanceState, onPause
methods in corresponding methods of Activity of Fragment.
class MyActivity extends Activity{
private ChronosConnector mConnector;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mConnector.onCreate(this, savedInstanceState);
}
@Override
protected void onResume() {
super.onResume();
mConnector.onResume();
}
@Override
protected void onSaveInstanceState(@NonNull final Bundle outState) {
super.onSaveInstanceState(outState);
mConnector.onSaveInstanceState(outState);
}
@Override
protected void onPause() {
mConnector.onPause();
super.onPause();
}
}
- You may extend an already set up class from com.redmadrobot.chronos.gui package. In that case you would have a [wrapper interface] (https://github.com/RedMadRobot/Chronos/blob/master/chronos/src/main/java/com/redmadrobot/chronos/gui/ChronosConnectorWrapper.java) of ChronosConnector in your Activity or Fragment.
class MyActivity extends ChronosActivity{
}
class MyDialogFragment extends ChronosSupportDialogFragment{
}
After you set up your Activity of Fragment (usually it only required once per project to define base classes), you can start using Chronos.
The main container for business logic workflow in Chronos is ChronosOperation. As a user of Chronos, you should extend ChronosOperation
with your own classes, defining what exactly needs to be done in its run()
method. Also it is very important to create a subclass of ChronosOperationResult for each operation, so that lately it would be possible do distinguish one operations result from another's (it is required due to [type erasure policy in Java] (https://docs.oracle.com/javase/tutorial/java/generics/erasure.html), which prevents code from distinguish two classes with one generic parent in runtime).
class MyOperation extends ChronosOperation<BusinessObject> {
@Nullable
@Override
//Chronos will run this method in a background thread, which means you can put
//any time-consuming calls here, as it will not affect UI thread performance
public BusinessObject run() {
final BusinessObject result ;
// here you should write what you do to get the BusinessObject
return result;
}
@NonNull
@Override
// To be able to distinguish results from different operations in one Chronos client
// (most commonly an activity, or a fragment)
// you should create an 'OperationResult<>' subclass in each operation,
// so that it will be used as a parameter
// in a callback method 'onOperationFinished'
public Class<? extends ChronosOperationResult<BusinessObject>> getResultClass() {
return Result.class;
}
public final static class Result extends ChronosOperationResult<BusinessObject> {
}
}
When your GUI is set up, and an Operation is created, you only need to launch it by calling chronosConnectorInstance.runOperation(new MyOperation())
or runOperation(new MyOperation())
if you extended a pre-defined GUI class. At this point Chronos begins executing the Operation in background (actually, it may not do it instantly if there are a plenty of running operations already). You may call runOperation()
no matter what state the Activity has, its result will be delivered only after the Activity passes onResume()
.
class MyActivity extends ChronosActivity{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Button startButton = (Button) findViewById(R.id.button_start);
startButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(final View v) {
// call the 'runOperation' method and it will begin executing of the operation
// in background thread, so it will not block your GUI.
runOperation(new MyOperation());
// after run is started, you can rotate, or put the sample to background
// but the result of the operation will be delivered to an 'onOperationFinished' method
// when the app goes to foreground once again.
}
});
}
}
To be able to get operations result you need to create a proper method in you GUI class. It must have a following signature public void onOperationFinished(MyOperation.Result result)
, where MyOperation.Result
matches with what your operations getResultClass()
method returns. Thats it, you don't have to manually subscribe or enable result getting when your Activity enters its resumed stage, or do anything else.
The onOperationFinished()
method will be called when the operation run is complete. To get a data, generated by the operation, you should use OperationResult's method getOutput()
. But it is more reasonable to firstly call isSuccessful()
method, because there might has happened an exception in the run()
method of the Operation. In that case, you will get an access to the exception via getError()
method of OperationResult.
class MyActivity extends ChronosActivity{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Button startButton = (Button) findViewById(R.id.button_start);
startButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(final View v) {
// call the 'runOperation' method and it will begin executing of the operation
// in background thread, so it will not block your GUI.
runOperation(new MyOperation());
// after run is started, you can rotate, or put the sample to background
// but the result of the operation will be delivered to an 'onOperationFinished' method
// when the app goes to foreground once again.
}
});
}
public void onOperationFinished(final MyOperation.Result result) {
if (result.isSuccessful()) {
showData(result.getOutput());
} else {
showDataLoadError(result.getError());
}
}
private void showData(BusinessObject data){
//...
}
private void showDataLoadError(Exception exception){
//...
}
}
The description above does cover only the basic scenario of Chronos usage. The following articles covers more complex usage cases:
- [Single run mode] (https://github.com/RedMadRobot/Chronos/wiki/Sinlge-launch-mode)
- [Broadcast run mode] (https://github.com/RedMadRobot/Chronos/wiki/Broadcasting-results)
- [Canceling runs] (https://github.com/RedMadRobot/Chronos/wiki/Canceling-operations)
For additional info, please, look at the Sample app code.