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 and use module libraries on maven
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.
Module | Shared Resources | Initialization | |
---|---|---|---|
Opensrp Context | Database | ||
Core | required | - | CoreLibrary.init(context()); |
Native Form | - | - | - |
Growth Monitoring | required | required | GrowthMonitoringLibrary.init(context(), getRepository()); |
Immunization | required | required | 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
Hacks/Tricks/Tweaks
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