preface
The company consists of three business lines, each of which has its own app. Function modules inevitably overlap ~ For example, the live broadcast function was only used in line A, but due to business expansion, now line B and C also need to use the live broadcast function. At this point, it is necessary to make the live broadcast function into an independent live broadcast component for the use of three business lines.
conceived
Now that we’re going to make live as a component, what are the aspects that need to be considered?
- It can run independently and test the function of the component separately. It can also be used as an SDK for other projects
- Unified management: deployed to the privatized warehouse, other projects can be configured reference
Based on the practice
Global control configuration
The configuration in gradle.properties can be used directly in a project
# Whether to use isModule=true as moduleCopy the code
Build. Gradle configuration
- Configure the Android build plug-in
If (ismodule.toboolean ()){// lib apply plugin: 'com.android.library'}else{// Apply plugin: 'com.android.library'} 'com.android.application' }Copy the code
- Disable the applicationId configuration
Can’t have configuration as library or compile an error: Library projects cannot set applicationId. applicationId is set to ‘com.example.live’ in default config.
android { ... defaultConfig { if(! isModule.toBoolean()){ applicationId "com.example.live" } ... }Copy the code
Androidmanifest.xml configuration
1. Run independently
To run independently, you need to configure the Application and start the Activity
// Normal template <application Android :allowBackup="true" Android :icon="@mipmap/ic_launcher" Android :label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.TestAndroidManifest"> <activity android:name=".MainActivity" android:exported="true"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application>Copy the code
2. Use it as a module
If used as a component by other projects, the application and startup entry configurations need to be modified
Intent-filter <activity android:name=".mainActivity "intent-filter <activity android:name=".mainActivity" android:exported="true"> </activity> </application>Copy the code
There are two questions:
- Can the property configuration in application not be removed?
After compiling, the AndroidManifest of all modules will be merged together, and an error will be reported if the same attributes are configured differently
Manifest merger failed : Attribute application@name value=(com.example.moduledemo.MainApplication) from AndroidManifest.xml:7:9-40
is also present at [:live] AndroidManifest.xml:11:9-56 value=(com.example.live.LiveApplication).
Suggestion: add 'tools:replace="android:name"' to <application> element at AndroidManifest.xml:6:5-23:19 to override.
Copy the code
App-module: Replace =” Android :name”; app-Module :replace=” Android :name” The following rules can be summarized by checking the output Androidmanifest.xml file through different configuration and rebuild:
- If only one Module is configured with a custom Application, use that application directly
- If each module is configured with a custom Application, conflicts need to be resolved. The application of the last compiled module will be used (for example: In demo, app-Module depends on live-Module. If you configure custom application, you will use the app defined in app-Module.
- Intent-filter (intent-filter) ¶
The merged file contains two activities that contain the information to start them. When you install your app, you’ll notice that there are two launch ICONS on your desktop, and clicking on them will behave the same way: open the first activity with the MAIN and LAUNCHER configured. Therefore, there is no need to keep this configuration.
3. Dynamically configure the AndroidManifest
Based on the above analysis, androidmanifest.xml needs to be adjusted to be used as a module and run as a standalone app. Then it is necessary to configure and use different AndroidManifest files according to the configuration
- Added Androidmanifest.xml for SDK in live-Module
Build. gradle configuration in live-Module dynamically references different Androidmanifest.xml
android {
...
sourceSets {
main {
if(isModule){
manifest.srcFile 'src/main/module/AndroidManifest.xml'
}else{
manifest.srcFile 'src/main/AndroidManifest.xml'
}
}
}
}
Copy the code
conclusion
At this point, you can control whether to use the Live component as library by modifying the liModule in gradle.properties. Here is a question to consider: if we have several components like Live in our project, do they all need to do such tedious configuration? Can you extract these configurations for unified management?
To optimize the
1. Extract independent APP build scripts
Create a common_app_build.gradle file in the project root directory
apply plugin: 'com.android.application' android {compileSdk 31 defaultConfig {minSdk 21 targetSdk 31 versionCode 1 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } sourceSets { main { manifest.srcFile 'src/main/AndroidManifest.xml' } } }Copy the code
2. Extract the build Library script
Create a common_LIBRary_build.gradle file in the project root directory
apply plugin: 'com.android.library' android {compileSdk 31 defaultConfig {minSdk 21 targetSdk 31 versionCode 1 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } sourceSets { main { manifest.srcFile 'src/main/module/AndroidManifest.xml' } } }Copy the code
3. Create a Course Module (for verification)
4. Modify build.gradle for live and Course modules
The following uses the Live Module as an example
If (isModule.toboolean ()) {apply from: '.. /common_library_build.gradle' } else { apply from: '.. /common_app_build.gradle' } android { defaultConfig { if(! isModule.toBoolean()){ applicationId "com.example.live" } } }Copy the code
Subsequent similar components require only a simple configuration to achieve the first idea
The module released
Here’s an example of how to use the Live Module: # Google Docs: Use Maven Publish plugin
Publish the Live Module to the local repository
Add the following configuration to build.gradle in the Live Module
afterEvaluate { publishing { repositories { maven { url uri(".. /repo") } } publications { maven(MavenPublication) { from components.release groupId "com.example.live" artifactId Modulelive "version "1.0.0"}}}}Copy the code
The above configuration specifies to publish live to the project /repo/ directory. After sync completes, a Publish Task appears in live
Double-clicking Publish generates the aar file in the REPo
The build configuration root. Gradle
In order to use the AAR in the REPO, you need to add configuration
buildscript {
repositories {
...
maven {
url('repo')
}
}
...
}
Copy the code
For use in app: configure build.gradle
dependencies { ... / / no direct reference to the project/project/API (' live ') / / to the configuration implementation 'com. Example. Live: modulelive: 1.0.0'... }Copy the code
The Live component can be used normally if rebuilt.
Publish to a remote repository
Because the project environment of different business lines is different, it is inconvenient to publish to the local project directory. Consider publishing components to a private repository within the company for use by all project teams:
publishing { ... // Repository url = "http://...." The credentials {username '' password ''}}}}Copy the code
conclusion
The above has mainly covered some of the basics of Android componentization and some of the flow of how to publish components. Of course, componentization includes more than that, including:
- Intercomponent communication
- Component jump
- Componentization confusion
- Component Resource Conflict
- .
These aspects are in the componentized design needs to think and deal with the subsequent gradually improve the content of this piece
Gitee: indicates the Demo address