Android Architecture
Architecture
Typical Android apps look like this
And this
Looking at this I am building an app with the architecture of
The was discussion on god class which I had not heard before
- Contains a high number of components
- Components are coupled
- Lengthy class
Avoid a all costs or don't cos I like getting rid of them
Design Patterns
Just a reminder of the design patterns but with maybe a more Android flare.
MVC
MVP
MVVM
Summary
Clean Architecture
Activity Lifecycle
Here is a simplified version of the lifecycle
By implementing the addObserver and don't forget the removeObserver the functions in the component (object instance) are envoked.
For example add
...
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
myLocationManager = new MyLocationManager(this,mTracker);
checkLocationPermission();
getLifecycle().addObserver(myLocationManager);
}
...
And in the Manager Class the clean() function is called when the lifecycle is STOP.
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
public void clean() {
Log.d(TAG, "clean() called");
if(mGoogleApiClient !=null) {
mGoogleApiClient.disconnect();
}
final LifecycleOwner lcOwner = (LifecycleOwner)mCon;
lcOwner.getLifecycle().removeObserver(this);
mCon = null;
}
Application Tidy Up
Introduction
Here is an overview of the app prior to looking at it. All of the code is in on Main Activity
Step 1
- Created TrackerActivity which extends AppCompatActivity and will be now good for other activities
- Move Tracker to its own class and implement the Lifecycle Observer interface
- When using lifecycle observer we need to remote it on destory
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
public void trackOnDestroy() {
Log.d(TAG, "trackOnDestroy called");
((AppCompatActivity) con).getLifecycle().removeObserver(this);
// mQueue.add(generateTrackingStringRequest("destroy"));
}
Step 2
- Moved CoinModel, Divider and MyCryptoAdapter to their own files in recview package
- Add LocationManager, implemented lifecycle observer
- Added create and destruction of FusedLocationProviderClient in lifecyle
- Added disconnect of GoogleAPiClient and removal of lifecycle observer
@OnLifecycleEvent(Lifecycle.Event.ON_START)
public void init() {
Log.d(TAG, "init() called");
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(mCon);
}
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
public void clean() {
Log.d(TAG, "clean() called");
if(mGoogleApiClient !=null) {
mGoogleApiClient.disconnect();
}
final LifecycleOwner lcOwner = (LifecycleOwner)mCon;
lcOwner.getLifecycle().removeObserver(this);
mCon = null;
}
Step 3
- Created a LocationActivity to contain all of the logic for the runtime permission to use Location
- Add LocationManger to LocationActivity
- Change MainActivity to be derived from LocationActivity
Current State 01
Step 4 And Manual View Model and Interface
- Create a crypto view model
- Move network calling to ViewModel
- Move storage calls to to ViewModel
- Create an interface from the model to the view with updateData and setError
- MainActivity
- v*Change MainActivity to use ViewModel for fetchData
- Implement interface
@Override
public void updateData(List<CoinModel> data) {
mAdapter.setItems(data);
mAdapter.notifyDataSetChanged();
mSwipeRefreshLayout.setRefreshing(false);
}
@Override
public void setError(String msg) {
showErrorToast(msg);
}
Step 5 And Android View Model and Interface
- Added package android.arch.lifecycle:extensions
- Extended view model from android ViewModel
- Replace manual viewmodel creation in MainActivity. The ViewModel requires you to pass the lifeCycle owner and the ViewModel class
mViewModel = ViewModelProviders.of(this).get(CryptoViewModel.class);
Using ViewModel we should not reference other Android Components as the LifeCyle of them may differ e.g. MainActivity.