Skip to content
This repository has been archived by the owner on Sep 11, 2023. It is now read-only.

How to use Chronos

MaximEfimovRMR edited this page Apr 27, 2015 · 8 revisions

There are four steps you should take to fully integrate Chronos to your app.

Step one – setting up GUI

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();
    }
}
class MyActivity extends ChronoActivity{
}
class MyDialogFragment extends ChronoSupportDialogFragment{
}

After you set up your Activity of Fragment (usually it only required once per project to define base classes), you can start using Chronos.

Step two – writing down business logic

The main container for business logic workflow in Chronos is Operation. As a user of Chronos, you should extend Operation 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 OperationResult 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 Operation<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 OperationResult<BusinessObject>> getResultClass() {
        return Result.class;
    }

    public final static class Result extends OperationResult<BusinessObject> {

    }
}

Step three – running the operation

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 ChronoActivity{
    @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.
            }
        });
    }
}

Step four – handling the result

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 ChronoActivity{
    @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){
        //...
    }
}

What else?

The description above does cover only the basic scenario of Chronos usage. The following articles covers more complex usage cases:

For additional info, please, look at the Sample app code.

Clone this wiki locally