OpenSRP Client Refactor and Clean Up

This page is for documenting the Client Refactor and Cleanup work.

Child Page


OpenSRP Client code (path branch)  has been refactored to several modules and applications.

A module consists of an android library and a sample application. The Library contains the components (classes and views) that will be used by different application, while the sample application highlights simple use cases of these components. The sample application can also be used to test code changes in the library.

A Library should emit/generate an Android archive (.aar) file that will  be pushed to maven. An Application will then download the maven file and add it as a compile dependency. For more info, checkout How to upload Android client libraries to Maven/Sonatype

Modules

Core module

https://github.com/OpenSRP/opensrp-client-core

Native form

https://github.com/OpenSRP/opensrp-client-native-form

Growth Monitoring

https://github.com/OpenSRP/opensrp-client-growth-monitoring (depends on core)

Immunizations

https://github.com/OpenSRP/opensrp-client-immunization (depends on core and native-form)

Applications

https://github.com/OpenSRP/opensrp-client-path (depends on core, native-form, growth-monitoring and immunization modules)

Adding a module as a dependency

To include a module in your application, add the compile dependency for that module in the build.gradle file of your application.

The following code block shows how modules were added to opensrp-client-path application.

dependencies {
    compile('org.smartregister:opensrp-client-native-form:1.0.0-SNAPSHOT@aar') {
        transitive = true
        exclude group: 'com.android.support', module: 'recyclerview-v7'
    }
    compile('org.smartregister:opensrp-client-core:1.0.0-SNAPSHOT@aar') {
        transitive = true
        exclude group: 'com.github.bmelnychuk', module: 'atv'
    }
    compile('org.smartregister:opensrp-client-immunization:1.0.0-SNAPSHOT@aar') {
        transitive = true
    }
    compile ('org.smartregister:opensrp-client-growth-monitoring:1.0.0-SNAPSHOT@aar') {
        transitive = true
    }
...
}
NB: When transitive is set to true, the dependencies of that module will also be included.

Initializing a module

Module that use shared resources, that is, OpenSRP context (org.smartregister.Context) and database (net.sqlcipher.database.SQLiteOpenHelper) should be initialized when the application starts.

Initialization is meant to pass the shared resource from the application to the modules.

Shared resources are created and managed at the application level and only used by the modules.

For the database, migration scripts are managed by the application, different applications can have different migration scripts.

The app should have one instance of OpenSRP context, which is created by the application and passed to the modules.

Each module that uses shared resources has a Singleton module library class that's used to access the context and database components e.g. org.smartregister.CoreLibrary


To create a unique OpenSRP context in Android android.app.Application class, the the code block below.

public class YourApplication extends DrishtiApplication {
    private Context context;
	...

    @Override
    public void onCreate() {
        super.onCreate();

		...

        context = Context.getInstance();
        context.updateApplicationContext(getApplicationContext());

		// If you use FTS 
        context.updateCommonFtsObject(createCommonFtsObject());

		... 
    }

	public Context context() {
        return context;
    }

...
}


To create the database, checkout the following code block.

public class YourApplication extends DrishtiApplication {
   
	...

	@Override
    public Repository getRepository() {
        try {
            if (repository == null) {
                repository = new YourRepository(getInstance().getApplicationContext(), context());
                
				// Initialize local repositories
 				uniqueIdRepository();
				...
            }
        } catch (UnsatisfiedLinkError e) {
            logError("Error on getRepository: " + e);

        }
        return repository;
    }

	// Initializing a local repository
	public UniqueIdRepository uniqueIdRepository() {
        if (uniqueIdRepository == null) {
            uniqueIdRepository = new UniqueIdRepository((YourRepository) getRepository());
        }
        return uniqueIdRepository;
    }

	// Accessing a module repository
	public VaccineRepository vaccineRepository() {
        return ImmunizationLibrary.getInstance().vaccineRepository();
    }  

...
}
NB: Only initialize local repository. Module repositories are accessed using its library getInstance method.


The table below shows the modules, their shared resources and how they are initialized.

ModuleShared Resources

Initialization

Opensrp ContextDatabase
Corerequired-
CoreLibrary.init(context());
Native Form--

-

Growth Monitoringrequiredrequired
GrowthMonitoringLibrary.init(context(), getRepository());  
Immunizationrequiredrequired
ImmunizationLibrary.init(context(), getRepository(), createCommonFtsObject());  
NB: Native form is not initialized because it does not require the shared resources.


To initialize modules in your Android android.app.Application, checkout the code below.

public class YourApplication extends DrishtiApplication {
    ...

    @Override
    public void onCreate() {
        super.onCreate();

		...

   		//Initialize Modules
        CoreLibrary.init(context());
        GrowthMonitoringLibrary.init(context(), getRepository());
        ImmunizationLibrary.init(context(), getRepository(), createCommonFtsObject());
    }
...
}

Code CleanUp

Codacy tool has been linked with github and will review code changes after a pull request has been created or updated.

Only the file changed will be reviewed. Codacy reviews the code changes in these files.

Developers are encouraged to open DNM pull requests to trigger reviews rather than wait until the actual PRs are created.

DNM stands for Do Not Merge, for example, “DNM: Fix some issue”

Protected Branch

The master branch in the modules and application has been set up as a protected branch.

This means that pull requests to the master branch should be reviewed.

Status check (travis and codacy) should pass.

Development Hacks

1. Do not include launcher intent filter in your library

2. Do not include theme/styles in library. Add theme/styles in the sample application or in your application.

3. To remove unused imports checkout Removing unused imports in Android Studio

4. To analyze using android lint checkout this link