preface
The author is in the arrangement and induction of knowledge. Gradle’s use of multiple dimensions has always been overlooked. For example, in the project, we have encountered. The international version of the app uses Google Pay. The domestic version uses wechat Pay. The SDK of Google Pay needs to be integrated separately from the SDK of wechat Pay. implementation
- The international version has only and only the Google Pay SDK
- The domestic version only has the SDK of wechat Pay
The reason is simple. Apk will not be that large when compiled.
In this paper, Gradle multidimensional analysis. Please correct any mistakes.
What is multidimensional
Create a new project. A debug and Release will appear when you click on the Build Variants TAB in the lower left corner of AS
These are the two default variants that development tools create for us. Both of these are visible in build.gradle. We don’t care.
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'}}Copy the code
If we add an international variant to buildTypes for example
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
/ / international version
international{
}
}
Copy the code
“International” will appear in Build Variants
Pay attention to
Currently all three variants are in one dimension. What if I wanted to turn the national and international editions into a new dimension?
You can find it on the official website. When multiple dimensions need to be configured. ProductFlavors is an option
// Dimensions need to be specified
flavorDimensions "nation"
productFlavors{
/ / international version
international{
}
/ / domestic version
domestic{
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'}}Copy the code
After the above configuration is complete. So now there are two dimensions. One is debug or release which is also the default dimension that AS gives us. And then there’s the dimension nation that we created ourselves. To check if it’s international or domestic.
Now I will look at our Build Variants
A small summary
From the small example above. We can tell. Dimensions are nothing more than categorizing our variants. Form a variation of dimension 1 times dimension 2. It is convenient for us to achieve different apK with different functions in the actual development, just like our top requirements.
- The international version has only and only the Google Pay SDK
- The domestic version only has the SDK of wechat Pay
How can more dimensions be used
Only two dimensions were demonstrated earlier. But I need more dimensions in my actual project. For example, a practical problem we encountered in our project. The Taiwanese version, though, is also planned for an international version. Because it’s all Google Pay. But this feature is only partially released. Not all of them. That’s when I need one more dimension. Decide if you need to disable payment.
flavorDimensions "nation"."pay"
productFlavors{
/ / international version
international{
dimension "nation"
}
/ / domestic version
domestic{
dimension "nation"
}
// Display payment
showpay{
dimension "pay"
}
// Do not display payment
hidepay{
dimension "pay"
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'}}Copy the code
Although it is configured in productFlavors. But for each variant it uses a dimension to specify which dimension it is in.
So now I have three dimensions. In addition to the previous two, there is an additional dimension to determine whether to display payment. So the current variant of alpha is going to be 2 x 2 x 2 8
Personally, I don’t think more dimensions is better. The more follow-up work, the more trouble. In the actual project. Finally whether to pay or not I did the extra configuration using buildConfigField
flavorDimensions "nation"
productFlavors{
/ / international version
international{
buildConfigField("Boolean"."isShowPay"."false")}/ / domestic version
domestic{
buildConfigField("Boolean"."isShowPay"."true")}}Copy the code
The role of dimensions
Go back to the example. Two dimensions are created.
- release / debug
- International/Domestic edition
Create the international and domestic folders under SRC. Code for placing different content.
What do we mean by different content code?
Let’s put it this way. In general. Our code is placed SRC /main/ Java /… The following. In order to make a distinction. For example, if the international version is displayed in the international version and the domestic version is displayed in the domestic version, you can use SRC /main/ Java /… The following code is copied to different folders. Then modify the code. So when you specify the version, you compile the code in the corresponding file.
It’s pale to say so. The author simulates to write an example. The requirement is that different compilations display different text.
The code is very simple and looks like this. Just display it in the TextView
object DebugTools {
fun getFlavors(a): String {
return "This is the default."}}Copy the code
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?). {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
findViewById<TextView>(R.id.textview).text = DebugTools.getFlavors()
}
}
Copy the code
The default directory structure is as follows. Very simple. After normal operation. It says this is the default
I created two different folders. And copy all the code into the corresponding variant. Pay attention to. At this point the SRC/main/Java /… The code needs to be deleted. The reason for the deletion is because. SRC /main/ Java /… Let’s compile it. If you do not delete it, you will have two MainActivities.
That’s what I mean by copying all the code.
I’m sure you see the problem. If I ever need to change a class like DebugTools. Then all variants need to be modified. It’s too much trouble. It’s totally out of line with our design specifications.
In a real project, we would put the generic parts in SRC /main/ Java /… , only place the differentiated code in the corresponding variants folder. For example, in the simple example we did. Only DebugTools is different. So let’s just differentiate this one. The following example
Packaging different dependencies
You know the dimensions and how to configure them. There is another problem. What I want to introduce is different dependencies. If we just use implementation. Both domestic and international editions will introduce this library. That’s not what I wanted. What I want is that the domestic version only has wechat SDK. The international version only has Google Pay SDK.
For demonstration purposes. The author will
- Use of international edition
Glide
Load the frame as an image - Use of domestic version
Coil
Load the frame as an image
In fact, the official website also explains how to configure
Just prefix the dependency with the corresponding variant name
// The international version uses Glide
internationalImplementation 'com. Making. Bumptech. Glide: glide: 4.12.0'
internationalAnnotationProcessor 'com. Making. Bumptech. Glide: the compiler: 4.12.0'
// The domestic version uses Coil
domesticImplementation("IO. Coil - kt: coil: 1.2.0")
Copy the code
It is then possible to happily load images using different dependencies under different variants of folders