Android组件化开发的意义何在?

安卓组件化开发的意义
当项目比较大需要多人协同开发的时候,组件化开发可以使大家分模块开发,并且不会互相影响。并且可以单独调试,不受其他模块制约。

项目结构解析

创建一个主应用,两个子应用(既可以做应用,也可以作为主应用的依赖),一个base库实现主应用和子应用的通讯。创建后项目结构如下
Android组件化开发的意义何在?_第1张图片
image

统一项目编译版本

  • gradle.properties文件设置统一版本
 # 统一编译版本等信息
 compile_Sdk_Version=28
 min_Sdk_Version=15
 target_Sdk_Version=28
  • 修改app、loginmodule、memodule、mudulelibrary的编译版本,以app为例
 apply plugin: 'com.android.application'
​
 android {
 compileSdkVersion compile_Sdk_Version.toInteger()
 defaultConfig {
 applicationId "com.syw.modulesdemo"
 minSdkVersion min_Sdk_Version.toInteger()
 targetSdkVersion target_Sdk_Version.toInteger()
 versionCode 1
 versionName "1.0"
 testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
 }
 buildTypes {
 release {
 minifyEnabled false
 proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
 }
 }
 }

设置application和library切换开关

  • gradle.properties文件设置切换开关
 # application和library切换开关
 isLoginApplication=true
 isMeApplication=true
  • 主应用动态添加依赖
 //不要忘记toBoolean()
 if (!isLoginApplication.toBoolean()) {
 implementation project(':loginmodule')
 }
 if (!isMeApplication.toBoolean()) {
 implementation project(':memodule')
 }
 implementation project(':modulelibrary')
  • 子应用切换application和library、动态设置applicationId、动态设置AndroidManifest.xml、添加基础依赖。以login模块为例
 //1.动态设置application或library
 if (isLoginApplication.toBoolean()){
 apply plugin: 'com.android.application'
 }else{
 apply plugin: 'com.android.library'
 }
​
 android {
 compileSdkVersion compile_Sdk_Version.toInteger()
​
 defaultConfig {
 //2.library不存在applicationId
 if (isLoginApplication.toBoolean()){
 applicationId "com.syw.loginmodule"
 }
 minSdkVersion min_Sdk_Version.toInteger()
 targetSdkVersion target_Sdk_Version.toInteger()
 versionCode 1
 versionName "1.0"
 testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
 }
​
 buildTypes {
 release {
 minifyEnabled false
 proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
 }
 }
​
 //    3.library状态下AndroidManifest.xml没有application信息,不设置启动activity
 sourceSets{
 main{
 if (isLoginApplication.toBoolean()){
 manifest.srcFile 'src/main/AndroidManifest.xml'
 }else{
 manifest.srcFile 'src/main/manifests/AndroidManifest.xml'
 }
 }
 }
 }
​
 dependencies {
 implementation fileTree(include: ['*.jar'], dir: 'libs')
 implementation 'com.android.support:appcompat-v7:28.0.0'
 implementation 'com.android.support.constraint:constraint-layout:2.0.2'
 testImplementation 'junit:junit:4.12'
 androidTestImplementation 'com.android.support.test:runner:1.0.2'
 androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
 implementation project(':modulelibrary')
 }

依赖库的manifest.xml

 
 
 
 
 

基础库设置

基础库设置接口,由子项目实现

以login模块为例,编写ILoginService

 public interface ILoginService {
 void launch(Context context);
​
 Fragment getFragment(FragmentManager fragmentManager, int containerId, Bundle bundle);
 }

编写接口管理类

public class ServiceFactory {
 // 单例模式
 private static final ServiceFactory instance=new ServiceFactory();
 public ServiceFactory(){}
 public static ServiceFactory getInstance() {
 return instance;
 }
​
 private ILoginService iLoginService;
 private IMeService iMeService;
​
 public ILoginService getLoginService() {
 return iLoginService;
 }
​
 public void setLoginService(ILoginService iLoginService) {
 this.iLoginService = iLoginService;
 }
​
 public IMeService getMeService() {
 return iMeService;
 }
​
 public void setMeService(IMeService iMeService) {
 this.iMeService = iMeService;
 }
}

子项目完成具体实现

public class LoginBridge implements ILoginService {
 @Override
 public void launch(Context context) {
 Intent intent = new Intent(context, LoginActivity.class);
 context.startActivity(intent);
 }
​
 @Override
 public Fragment getFragment(FragmentManager fragmentManager, int containerId, Bundle bundle) {
 LoginFragment loginFragment=new LoginFragment();
 loginFragment.setFragmentData(bundle);
 fragmentManager.beginTransaction().add(containerId,loginFragment).commit();
 return loginFragment;
 }
}

跳转方法的调用

跳转的具体实现已经完成,现在的问题是怎么调用,我们想要实现的是在MainActivity中通过如下代码调用

 ServiceFactory.getInstance().getLoginService().launch(MainActivity.this);

那么现在的问题是,什么时候将LoginService设置到ServiceFactory,刚开始的时候还在想,既然已经依赖了loginmodule,为啥不直接跳转。仔细想想,这就违背了组件化的本意了,我们应该减少子项目和主项目之间的耦合,通过中间库的方式。 为了调用getLoginService,我们首先需要setLoginService,将实现类设置到ServiceFactory。于是就有了下面的方法

在子项目中创建一个方法,在主项目初始化的时候,通过主项目调用,子项目将实现类设置给ServiceManager
  • 我们首先需要在基础库创建一个接口,通过主项目调用,实现全部子应用设置Service
 public interface Appcompat {
 void initializa();
 }
  • 我们首先创建一个类,实现该接口,设置LoginService
 public class LoginApplication extends Application implements Appcompat {
 @Override
 public void initializa() {
 ServiceManager.getInstance().setLoginService(new LoginBridge());
 }
 }
  • 我们创建一个类,管理所有子项目设置Service的类。主项目通过反射的方法调用,实现全部子应用设置Service
 public class AppConfig {
 public static final String[] COMPONENT={
 "com.syw.loginmodule.LoginApplication",
 "com.syw.memodule.MeApplication"
 };
 }
  • 现在我们需要在主项目中调用方法了,首先在主项目初始化的时候,通过initializa方法调用,已经让所有子项目setXxxService。
 public class MainApplication extends Application {
 @Override
 public void onCreate() {
 super.onCreate();
 for (String component : AppConfig.COMPONENT) {
 try {
 Class clazz=Class.forName(component);
 Object obj = clazz.newInstance();
 if (obj instanceof Appcompat){
 ((Appcompat) obj).initializa();
 }
 } catch (Exception e) {
 e.printStackTrace();
 }
 }
 }
 }
  • 在需要使用的地方,即可直接getXxxService,然后调用方法
 public class MainActivity extends AppCompatActivity {
​
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
​
 findViewById(R.id.gologin).setOnClickListener(new View.OnClickListener() {
 @Override
 public void onClick(View v) {
 ServiceManager.getInstance().getLoginService().launch(MainActivity.this);
 }
 });
​
 findViewById(R.id.gome).setOnClickListener(new View.OnClickListener() {
 @Override
 public void onClick(View v) {
 ServiceManager.getInstance().getMeService().launch(MainActivity.this);
 }
 });
​
 findViewById(R.id.gofragment).setOnClickListener(new View.OnClickListener() {
 @Override
 public void onClick(View v) {
 Bundle bundle=new Bundle();
 bundle.putString("name","张三");
 ServiceManager.getInstance().getLoginService().invokeLoginFragment(getSupportFragmentManager(),R.id.container,bundle);
 }
 });
 }
 }

应该还可以参考阿里的aroute框架,目前先暂时记录到这里 demo下载链接https://download.csdn.net/download/ForMuHan/13067005

你可能感兴趣的:(Android组件化开发的意义何在?)