bin^2

bin^2

discord server
twitter

How I developed Android App - Journey

How I Develop Android Apps - Journey#

Series
2022-01-06
Android
Article/Done/Published

Journey#

Phase One: Single App, Single Module#

The initial requirement was simple, only one app was needed, and all the functionalities were directly placed in one module.

component app

Phase Two: Single App, Multiple Feature Modules#

As the project progressed, there were independent feature modules that required customization. One solution was to use DynamicFeature.

component app
component dynamic_feature_a
component dynamic_feature_b
component dynamic_feature_n
dynamic_feature_a --> app
dynamic_feature_b --> app
dynamic_feature_n --> app

DynamicFeature requires support from the app market. It is not commonly used for cases that require independent deployment. However, there is also https://github.com/iqiyi/Qigsaw, which allows self-deployment of an app market that supports dynamic features. But the deployment process is too complex.
Another solution is pluginization, which can be done at runtime or compile-time.
Compile-time pluginization is relatively simple to implement, as it only requires dynamically modifying the app's dependencies. At runtime, all plugin implementations are obtained through reflection and the corresponding methods are called.

component app
component feature_a
component feature_b
component feature_n
app --> feature_a
app --> feature_b
app --> feature_n

Compile different plugin modules
build.gradle

	
dependencies{
	if(useFeature("feature_a")){
		implementation ":feature_a"
	}
	if(useFeature("feature_b")){
		implementation ":feature_b"
	}
}

Phase Three: Single App, Multiple Feature Modules, Single Common Module#

As the number of feature modules increased, there were many repeated library dependencies among different modules, and there could be version conflicts. To unify the version and usage of utility libraries, encapsulation was needed.
Therefore, a common library was introduced.
In principle, all dependencies related to non-core functionalities of feature modules should be placed in the common library, such as network requests, image processing, key-value storage, databases, etc.
Additionally, feature modules should not directly depend on third-party libraries; they should be encapsulated through the common library to facilitate future upgrades and migrations.

component app
component feature_a
component feature_b
component feature_n
app --> feature_a
app --> feature_b
app --> feature_n
component common
feature_a --> common
feature_b --> common
feature_n --> common

Phase Four: Interdependent Feature Modules#

As the number of feature modules increased, there was a need for inter-module communication. However, feature modules belong to the same layer from a hierarchical perspective, and direct dependencies between the same layer should be avoided to prevent circular dependencies.
Therefore, a common feature module (services) or service bus was introduced, where all feature modules provide services to other modules by implementing interfaces defined in the services module.
The common module and common feature module are collectively referred to as the Framework.

package apps{
	component app
}
package features{
component feature_a
component feature_b
component feature_n
}
app --> feature_a
app --> feature_b
app --> feature_n

package framework{
	component common

	component services {
		component feature_a_service
		component feature_b_service
		component feature_n_service
	}
}
features --> common
feature_a --> feature_a_service
feature_b --> feature_b_service
feature_n --> feature_n_service

There is another way to handle service calls between modules, which is to define a separate component for each feature module to be used by other modules. However, this can lead to exponentially complex dependency relationships. Therefore, it is better to manage all module's public services in a unified manner.

component feature_a
component feature_a_service
feature_a --|> feature_a_service

component feature_b
component feature_b_service
feature_b --|> feature_b_service

component feature_n
component feature_n_service
feature_n --|> feature_n_service

feature_a --> feature_b_service
feature_b --> feature_a_service
feature_n --> feature_a_service
feature_n --> feature_b_service

Phase Five: Focus on Functionality#

Registering functionalities in the market, app automatically discovers features.


package framework{
	package apps{
		component app
	}
	component common

	component services {
		component feature_a_service
		component feature_b_service
		component feature_n_service
	}
}

package features{
component feature_a
component feature_b
component feature_n
}
features --> common

app --> feature_a
app --> feature_b
app --> feature_n

feature_a --> feature_a_service
feature_b --> feature_b_service
feature_n --> feature_n_service
Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.