Toolset for android developers that contains base features for common tasks.
The project is divided to different modules:
- Toolset - features for make ur own Components that works and manages in Android Service (same process as ur app, and same thread). Presetes for networks, database and shared preferences tasks.
- UI - contains MVVM (Android Components) presets. Navigation (drawer layout) preset to manage side menu. Adapter Delegation preset to make listview more flexible on different types of items. Utils and etc.
- [sample] - contains example of features from [toolset] and [ui] package based on Reddit browsing.
- ipc - using android.os.Messenger and Observer pattern to observe data changes between different processes.
- [ipc_sample] - sample of ipc with Location Tracking Service.
There is an android service represented in
com.axmor.kash.toolset.service.CompositeServicewhich delegates service logic to
com.axmor.kash.toolset.service.ServiceCoreIt contains client components and manages them by certain lifeline. Default lifeline: When there first bind to service the core activates all components. When we lost binds on the service there 5 minutes before all components will be deactivated and the service will be closed. This time is interrupted if we have new binds before end.
To create and add new components (smth u wont to executing in androidservice) u should extend it by
com.axmor.kash.toolset.service.interfaces.Component and add in overrided buildComposite() method of ur implementation of CompositeService. See example:
com.axmor.kash.sample.core.AppServiceIf u want to get components from service u should use
com.axmor.kash.toolset.service.connection.CompositeServiceConnectionSee example:
com.axmor.kash.ui.mvvm.KashViewModelThere already 3 components for work with network (through Retrofit), database (through Room) and Repository that can contain both of network and database components. They all are used in [sample].
com.axmor.kash.toolset.local.db.service.KashDatabaseService
com.axmor.kash.toolset.network.KashNetworkApiService
com.axmor.kash.toolset.repository.KashEntityRepositoryServiceThe database component works with
com.axmor.kash.toolset.local.db.KashBaseDao
com.axmor.kash.toolset.local.db.KashDatabaseso u need to extends ur own from those classes.
There is a couple of public methods to work with SharedPreferences. It allows to put and get get primitives, Strings and Object(using json by Moshi).
com.axmor.kash.toolset.local.pref.SharedPreferencesHelperUtils to work with dates and json in package
com.axmor.kash.toolset.utilsThere are a couple of classes that represents mvvm (using Android Components) in 'mvvm' package and uses services from [toolset] module.
com.axmor.kash.ui.mvvm.KashViewModelIt implements
com.axmor.kash.toolset.service.connection.ConnectionNodeand connects to service through
com.axmor.kash.toolset.service.connection.CompositeServiceConnectionIt also contains
com.axmor.kash.ui.progress.ProgressLiveData
com.axmor.kash.ui.error.ErrorLiveDatato inform subscribers about showing/hiding of progress and errors. U can see example of usage in [sample]:
com.axmor.kash.sample.ui.reddit_list.RedditListViewModel
com.axmor.kash.sample.ui.favorites.FavoritesListViewModelKashActivity and KashFragment have same implementation. They connects to view model and subscribes on error and progress live data.
com.axmor.kash.ui.mvvm.KashActivity
com.axmor.kash.ui.mvvm.KashFragmentContains logic to make flexible adapter that can have different types of data and allow u easily manages this types between different adapters (uses RecyclerView.Adapter as base).
com.axmor.kash.ui.adapters.KashAdapterDelegateU need to extend ur own delegate by this where determine view holder and for wich type of data it is used. See example:
com.axmor.kash.sample.ui.adapter.news_list.RedditNewsAdapterDelegate
сom.axmor.kash.sample.ui.adapter.news_list.RedditNewsLoadingAdapterDelegatecom.axmor.kash.ui.adapters.KashBaseAdapterKashBaseAdapter contains data and KashAdapterDelegatesManager to manage different delegates. U can use this adapter or extend ur own. See example:
com.axmor.kash.sample.ui.adapter.news_list.RedditNewsAdapterContains base logic to create navigation items for drawer layout. First of all u need to extend
com.axmor.kash.ui.navigation.NavigatableScreenEnvSee example:
com.axmor.kash.sample.ui.main.MainMenuActivityTo detect when item (which represents fragment openning) is activated. This activity also contains
com.axmor.kash.ui.navigation.NavigationScenewhich u configures and where adds navigation items. NavigationScene class manages items and activates them when they are clicked. There already two items that represent Action Item (when ur want some action on click) and Fragment Item (when ur want to open fragment on click).
com.axmor.kash.ui.navigation.NavigationItemAction
com.axmor.kash.ui.navigation.NavigationItemRootFragmentThere only one class that detects when we arrived to end of the list view.
com.axmor.kash.ui.commons.InfiniteScrollListenerSee example:
com.axmor.kash.sample.ui.reddit_list.RedditListFragmentPlenty of common utils.
com.axmor.kash.ui.utils.ActivityUtilsWorks with activity manager.
com.axmor.kash.ui.utils.ImageViewExtensionsLoading images using picasso.
com.axmor.kash.ui.utils.MetricUtilsTransfering dp to px.
com.axmor.kash.ui.utils.NetworkUtilsDetecting network connection.
com.axmor.kash.ui.utils.OSUtilsDetecting os version.
com.axmor.kash.ui.utils.PackageInfoUtilsGetting information about current package.
com.axmor.kash.ui.utils.TextUtilsFormatting text with html.
com.axmor.kash.ui.utils.ViewGroupExtensionInflating views.
Ipc using Observer pattern and wraps over android.os.Messenger. See example in [ipc_sample] module.
First of all u should bind to Service. On the service side create Messenger and set Handler to this one. Get binder from created Messenger and send it back in onBinde(). See example in:
com.axmor.ipc_sample.tracking.ipc.TrackingServiceStubWhen u get binder on client side, create Messenger with one. Now u can send message to Service and handle them in Handler u created before. To make observable on some data create:
val observableClient = IPCObservableClient<TrackingService.PublicState>(callbackLooper)And send it throw messenger to service. On ther service side, when u get the message, create:
var publicState: IPCValueObservable<PublicState> = IPCValueObservable(PublicState(State.IDLE))
val clientProxy = IPCObservableClientProxy<TrackingService.PublicState>(msg.replyTo)
val observableWrapper = IPCObservableWrapper(publicState, looper)
val clientProxy.onObservableCreated(observableWrapper)Not u can addObserver to (on Client side):
val observableClient = IPCObservableClient<TrackingService.PublicState>(callbackLooper)
observableClient.addObserver(object : IPCObserver<TrackingService.PublicState> {
override fun onChanged(value: TrackingService.PublicState) {
var s = value.state
}
})and change data (on Service side):
var publicState: IPCValueObservable<PublicState> = IPCValueObservable(PublicState(State.IDLE))
publicState.setValue(PublicState(state))- Kotlin - Base language of project.
- Appcompat v7 27.0.0 - Uses activity that implements Lifecycle part of android components.
- Rxandroid and Rxjava - Calls to Service's Components.
- Retrofit2 and RetrofitRxjava - Network Calls.
- Moshi - Json serialization/deserialization.
- Lifecycle Extensions - Android Components.
- Room - Library to work with SQLLite by Google.
- Recycler View - Modern library to present lists of view.
- Picasso - Library to async loading images from network.