Android组件化实现,理解吸收

什么是组件化?

一个大型APP版本一定会不断的迭代,APP里的功能也会随之增加,项目的业务也会变的越来越复杂,这样导致项目代码也变的越来越多,开发效率也会随之下降。并且单一工程下代码耦合严重,每修改一处代码后都要重新编译,非常耗时,单独修改的一个模块无法单独测试。

组件化架构的目的是让各个业务变得相对独立,各个组件在组件模式下可以独立开发调试,集成模式下又可以集成到"app壳工程"中,从而得到一个具有完整功能的APP。

组件化每一个组件都可以是一个APP可以单独修改调试,而不影响总项目。

为什么使用组件化?

编译速度: 可以但需测试单一模块,极大提高了开发速度 超级解耦: 极度降低了模块间的耦合,便于后期的维护和更新 功能重用: 某一块的功能在另外的组件化项目中使用只需要单独依赖这一模块即可 便于团队开发: 组件化架构是团队开发必然会选择的一种开发方式,它能有效的使团队更好的协作

组件化实现

一、建立项目

我们新建一个moduleLearn的项目,这里面我们再新建几个module。module的建立是 file- > new module。

这里说明一下,我们建立了chat、contract、home这三个module,它们三个在建立的时候选择Phone & Tablet module模式。这三个模块, 就是我们要独立进行开发的。

commonlib在建立的时候,选择Android Library,它是做为公共组件存在

二、添加变量

让各组件可以根据变量值的变化来确定是否可以独立开发

在项目的根目录下,找到gradel.properties文件,在里面写下

#是否需要单独编译 true表示不需要 false表示需要

isNeedHomeModule = true
isNeedChatModule = true
isNeedContractModule = true

三、在各个子组件的build.gradle中进行修改

1,在头部进行修改

//根据是否独立运行,来改变module
if(!isNeedHomeModule.toBoolean())
{
    apply plugin: 'com.android.application'
}else{
    apply plugin: 'com.android.library'
}

2, android-> defaultConfig中的内容

android {
    compileSdkVersion 28
    defaultConfig {
   		//独立运行时,添加applicaton
        if(!isNeedHomeModule.toBoolean()) {
            applicationId "com.cg.home"
        }
        minSdkVersion 21
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
    }

三、修改各子组件的androidmanifest.xml文件

在src -> main 下面建立manifest文件夹,在里面再建立一个androidmanifest.xml文件,把外面的androidmanifest.xml的内容复制一份进来,并修改外面的androidmanifest.xml内容,修改什么呢,就是把默认的启动页去掉。

<?xml version="1.0" encoding="utf-8"?>


<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/AppTheme">
    <activity android:name=".MainActivity">


    </activity>
</application>

下面是正常的androidmanifest.xml

<?xml version="1.0" encoding="utf-8"?>


<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.cg.home">


    <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/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />


                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>


</manifest>

现在看到区别了吧,为什么要改这里呢,这里你不改的话,可以试一下,在不进行独立开发的时候,你一安装app,会有多个启动页面,这样就会在手上出现多个app的进入图标。

添加完androidmanifest.xml后,我们要去修改build.gradle文件,在android中添加

sourceSets{
        main{
			//这里我只是用home做的例子,每个module都要进行改,要判断相应的判断
            if(!isNeedHomeModule)
            {
                manifest.srcFile 'src/main/manifest/AndroidManifest.xml'
            }else{
                manifest.srcFile 'src/main/AndroidManifest.xml'
            }
        }
    }

四,去主app的build.gradle中添加引用

if(isNeedChatModule.toBoolean())
    {
        implementation project(':chat')
    }


    if(isNeedContractModule.toBoolean())
    {
        implementation project(':contract')
    }


    if(isNeedHomeModule.toBoolean())
    {
        implementation project(':home')
    }


    implementation project(':commonlib')

当进行独立开发的时候,就需要进行引用。

好,到这里,组件化就算处理完成了,运行一下,就可以看到,只要修改gradle.properties里面我们自定义的变量值,就可以实现是否独立开发了。

下面我们来看一下,ARouter的引用与使用。

我们定义了commonlib的作用就是为了能做共用的代码提取出来,但是ARouter里面的一些代码,却无法放到这里,不然总是会提示你错误。这算是一个坑吧。

现在我们把ARouter怎么引入做一个说明

一、所有module都引用一个commonlib。

二、在commonlib的buile.gradle中引入

compile "com.alibaba:arouter-api:1.5.0"

当然了,你可以不放在dommlib中,在每个module中独立加也行

三、在每个module中引入

annotationProcessor 'com.alibaba:arouter-compiler:1.2.2'

同时,在android -> defaultConfig中添加

android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "com.cg.modulelearn"
        minSdkVersion 21
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"


		//这里就是ARouter的引用
        javaCompileOptions {
            annotationProcessorOptions {
                arguments = [AROUTER_MODULE_NAME: project.getName()]
            }
        }
    }

这里要注意主app中也要添加

四、初始化ARouter是在主app中,定义一个我们自己的myAppllication.

public class myApplication extends Application {


    @Override
    public void onCreate() {
        super.onCreate();


        initRouter();
    }


    private void initRouter() {
        if(BuildConfig.DEBUG)
        {
            ARouter.openLog();
            ARouter.openDebug();
        }
        ARouter.init(this);
    }
}

这样就集成完了,现在看一下,如何跳转与传值。

一、在子module中我们要进行注解

//这里注意,这时必须是二级目录,这里写的path就是在主app中要调用的跳转路径
@Route(path="/home/main")
public class MainActivity extends AppCompatActivity {


    private TextView txt_homeTitle;


	//这里的title值,就是要传入的值,前面必须加上@Autowired
    @Autowired
    public String title;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_homemain);
        //将页面注入到ARouter中
        ARouter.getInstance().inject(this);
        Log.e("MainActivity.java(onCreate)", "行数: 25  title:" + title);
        initControls();
    }


    /**
     * 初始化控件
     */
    private void initControls() {
        txt_homeTitle = (TextView)findViewById(R.id.txt_homeTitle);
        txt_homeTitle.setText(title);
    }




}

主app中的代码

public class MainActivity extends AppCompatActivity {


    private Button btn_home;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //ARouter.getInstance().inject(this);
        initControls();
    }


    /**
     * 初始化控件
     */
    private void initControls() {
        btn_home = (Button)findViewById(R.id.btn_home);
        btn_home.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ARouter.getInstance().build("/home/main")
                        .withString("title","主app传过来的HOME名字")
                        .navigation();
            }
        });
    }
}

到此完成。这里只是简单的做一个使用记录。全文主要讲了在Android开发当中的组件化技术,以上是对组件化一个简单的介绍和理解以及组件化实现案例。更多有关Android组件化学习或进阶Android架构技术,可以参考《Android核心技术手册》点击可以查看详细栏内容。

相关推荐
Eastsea.Chen2 小时前
MTK Android12 user版本MtkLogger
android·framework
长亭外的少年10 小时前
Kotlin 编译失败问题及解决方案:从守护进程到 Gradle 配置
android·开发语言·kotlin
建群新人小猿12 小时前
会员等级经验问题
android·开发语言·前端·javascript·php
1024小神13 小时前
tauri2.0版本开发苹果ios和安卓android应用,环境搭建和最后编译为apk
android·ios·tauri
兰琛13 小时前
20241121 android中树结构列表(使用recyclerView实现)
android·gitee
Y多了个想法14 小时前
RK3568 android11 适配敦泰触摸屏 FocalTech-ft5526
android·rk3568·触摸屏·tp·敦泰·focaltech·ft5526
NotesChapter15 小时前
Android吸顶效果,并有着ViewPager左右切换
android
_祝你今天愉快16 小时前
分析android :The binary version of its metadata is 1.8.0, expected version is 1.5.
android
暮志未晚Webgl16 小时前
109. UE5 GAS RPG 实现检查点的存档功能
android·java·ue5
麦田里的守望者江17 小时前
KMP 中的 expect 和 actual 声明
android·ios·kotlin