Android 组件化开发搭建

目录

  模块化的开发流程


  模块化的开发流程

  1.      首先 我们建立一个主App,主app用来控制触发进入各个模块的入口,只是一个外壳,所有的逻辑在各个模块组件内部开发,各个模块以及外壳的app通信是采用阿里的路由框架进行的,稍后我会搭建一个可以各个模块的配置,以及运行环境。大家直接实战进行吧,在网上搜索一堆的模块化开发博客,倒不如自己亲自实践一下,原理都是一样,实践出真知吧。

  2.     首先我的AS是3.6.1 版本的,我们搭建一个主工程,我这里暂且命名时StoreApp,然后再在这个主工程下面创建三个子module工程和一个lib工程,分别命名module工程为home,mine,store工程,lib工程名为baselib,而lib工程主要用来依赖各个工程所需要依赖的资源库 。创建好了这些以后,我们知道module工程是可以独立运行的。接下来,我们得配置module工程为lib库作为依赖了。

  3.  在主工程的 gradle.properties文件下配置值三个控制home,mine,store作为库工程还是独立调试的可运行的module工程。我是这样配置的三个参数的:

    #控制子工程是以lib还是moudle的形式
    isShowHome = true
    isShowMine = true
    isShowStore= true
  4. 三个module工程的gradle配置都是一样的配置,这里我以home为例。在gradle的顶部加一个if判断句:
    if (!isShowHome.toBoolean()) {
        apply plugin: 'com.android.application'
    } else {
        apply plugin: 'com.android.library'
    }                                                                                                                                    这个是用来判断它为module还是lib库的 
    接下来在我们看到包名applicationId在其中也添加一个判断语句:
    if (!isShowHome.toBoolean()) {
        applicationId "com.android.xzl.home"
    }
    
  5. 接下来我们配置一下清单文件的资源:
    sourceSets {
        main {
            //控制两种模式下的资源和代码配置情况
            if (!isShowHome.asBoolean()) {
                manifest.srcFile 'src/main/module/AndroidManifest.xml'
            } else {
                manifest.srcFile 'src/main/AndroidManifest.xml'
                //集成开发模式下排除debug文件夹中的所有Java文件
                java {
                    exclude 'debug/**'
                }
            }
        }
    } 
    我们看到有个路径,我们没有建立这个时候,在main目录下建立一个module文件夹,但是然后将我们清单文件复制一份进去,但是要做一些修改。将application下的各种配置都删除掉,然后就留下一个theme属性就行了。我给大家先贴出一份我的module工程下的清单文件,然后是建立的module文件夹下的清单文件代码:
    home的module工程下的清单文件:
    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.android.xzl.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>
    而我们自己建立的文件夹的清单文件为:
    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.android.xzl.home">
    
    
        <application
            android:theme="@style/AppTheme">
            <activity android:name=".MainActivity"/>
    
        </application>
    
    </manifest>
  6. 好了,其余的mine和store的module工程gradle配置是一样的,但是要对应我们的之前在gradle.properties的配置的三个布尔值,记得把把那个改一下。当然我们也可以用一个布尔值配置三个moudle工程开关,这个看个人的喜欢。
  7. 接下来,我们配置一下baselib的库,首先我们用的是阿里的路由框架用来各个模块的通信,传参。在gradle中依赖一下:
    api 'com.alibaba:arouter-api:1.4.1'
    annotationProcessor 'com.alibaba:arouter-compiler:1.2.1'
    这里注意一下,我没有用implementation而是用了api,大家可以自行百度,看一下区别。接下来,我们在defaultConfig中还要加入:
    javaCompileOptions {
        annotationProcessorOptions {
            arguments = [AROUTER_MODULE_NAME: project.getName()]
        }
    }
    这下我们就配置好了路由框架了。这里有个注意点各个子工程要是用到路由框架都要再次在gradle中的依赖出加入:
    annotationProcessor 'com.alibaba:arouter-compiler:1.2.1'     和
    javaCompileOptions {
        annotationProcessorOptions {
            arguments = [AROUTER_MODULE_NAME: project.getName()]
        }
    }
    这个依赖,不然编译的时候会报alibaba:arouter找不到的错误。
  8. 接下来,我们在baselib库下建立BaseApplication,
    import com.alibaba.android.arouter.launcher.ARouter;
    
    public class BaseApplication  extends Application {
        private static  BaseApplication instance;
        @Override
        public void onCreate() {
            super.onCreate();
            instance=this;
            initRouter();
        }
        public static BaseApplication getInstance(){
            return instance;
        }
        private void initRouter(){
            if (BuildConfig.DEBUG) {
                //一定要在ARouter.init之前调用openDebug
                ARouter.openDebug();
                ARouter.openLog();
            }
            ARouter.init(this);
        }
    }
    然后建立一个路劲类RouterPath:
    /**
     * create by libo
     * create on 2018/12/25
     * description 路径跳转配置类
     */
    public class RouterPath {
        public static final String ROUTER_HOME = "/home/activity";
        public static final String ROUTER_MINE = "/mine/activity";
        public static final String ROUTER_STORE = "/store/activity";
    }
  9. 然后我们在主工程还有各个模块都依赖这个baselib
  10. 接下来我们在主工程的moudle下,
    implementation project(path: ':baselib')
    annotationProcessor 'com.alibaba:arouter-compiler:1.2.1'
    implementation project(path: ':mine')
    implementation project(path: ':home')
    implementation project(path: ':store')
    再次强调一下:使用路由框架还需要依赖:annotationProcessor 'com.alibaba:arouter-compiler:1.2.1'这个,还有加上
    javaCompileOptions {
        annotationProcessorOptions {
            arguments = [AROUTER_MODULE_NAME: project.getName()]
        }
    }
  11. 然后我们在主工程建立MainApplication继承baselib库的BaseApplication,记住在清单文件中声明一下:代码:
    /**
     * author : wulei
     * e-mail :
     * time   : 2020/04/04
     * desc   :
     */
    public class MainApplication extends BaseApplication {
    
        @Override
        public void onCreate() {
            super.onCreate();
        }
    }
  12. 如果你的jdk版本过低,在各个模块的gradle中加入:
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
  13. 然后你就可以写你的逻辑代码了我再我的主工程的MainActivity下的代码:
    public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    
        private Button mBtHome;
        private Button mBtMine;
        private Button mBtStore;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            ARouter.getInstance().inject(this);
            mBtHome = (Button) findViewById(R.id.bt_home);
            mBtMine = (Button) findViewById(R.id.bt_mine);
            mBtStore = (Button) findViewById(R.id.bt_store);
    
    
            mBtHome.setOnClickListener(this);
            mBtMine.setOnClickListener(this);
            mBtStore.setOnClickListener(this);
        }
    
        @Override
        public void onClick(View v) {
            switch (v.getId()) {
                case R.id.bt_home:
                    ARouter.getInstance().build(RouterPath.ROUTER_HOME).
                            withString("home_msg", "我传递了home页面过去").navigation();
                    break;
    
                case R.id.bt_mine:
                    ARouter.getInstance().build(RouterPath.ROUTER_MINE).
                            withString("mine_msg", "我是磊磊哥啊!!!!").navigation();
                    break;
    
                case R.id.bt_store:
                    ARouter.getInstance().build(RouterPath.ROUTER_STORE).
                            withString("store_msg", "进入了商店,买个东西再走吧!!!").navigation();
                    break;
            }
        }
    布局文件如下:
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity"
        android:orientation="vertical">
    
        <Button
            android:id="@+id/bt_home"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="跳转home界面"/>
    
        <Button
            android:id="@+id/bt_mine"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="跳转我的界面"/>
    
        <Button
            android:id="@+id/bt_store"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="跳转商店界面"/>
    
    </LinearLayout>

 14.我的home页面的代码如下:

@Route(path  = RouterPath.ROUTER_HOME)
public class MainActivity extends AppCompatActivity {
    @Autowired()
    String home_msg;
    private TextView mTvHome;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_home);
        ARouter.getInstance().inject(this);
        mTvHome = (TextView) findViewById(R.id.tv_home);
        mTvHome.setText(home_msg+"");
    }
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"
    android:gravity="center">

    <TextView
        android:id="@+id/tv_home"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        />

</LinearLayout>

15.在mine的逻辑代码如下:

@Route(path = RouterPath.ROUTER_MINE)
public class MainActivity extends AppCompatActivity {
    @Autowired
    String mine_msg;
    private TextView mTvMine;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ARouter.getInstance().inject(this);
        setContentView(R.layout.activity_mine);
        mTvMine = (TextView) findViewById(R.id.tv_mine);
        mTvMine.setText(mine_msg);

    }
}
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/tv_mine"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="这是默认的我的界面!!!!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

16:在store下的代码:

@Route(path= RouterPath.ROUTER_STORE)
public class MainActivity extends AppCompatActivity {
    @Autowired
    String store_msg;
    private TextView mTvStore;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_store);
        ARouter.getInstance().inject(this);
        mTvStore = (TextView) findViewById(R.id.tv_store);

        mTvStore.setText(store_msg);
    }
}

 

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/tv_store"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="这是商店的默认界面!!!!!!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

哈哈哈,最后警告一下,新建的module下的布局文件的名字不要全部一样的,到时候有冲突的额!!!接下来我们就可以试着运行项目了。

 

 

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值