Una exploración preliminar de la creación de componentes de Android: este artículo lo llevará hasta la oscuridad

Visión de conjunto

El proceso de desarrollo de software es también el proceso de evolución de la arquitectura, tomemos como ejemplo Android, desde los MVC, MVP, MVVP iniciales, hasta la posterior componentización y plug-in, pero al final todo es para un mejor mantenimiento del proyecto. , iteración, reducir los costos de desarrollo.

En el proceso de desarrollo de un proyecto, podemos poner todos los módulos funcionales en un módulo en la etapa inicial, para que podamos desarrollar rápidamente, pero a medida que el proyecto crece y aumenta la cantidad de desarrolladores y funciones, el código se volverá más y más más hinchado., el acoplamiento entre los distintos módulos se vuelve más y más pesado, y todo el cuerpo se ve afectado. En este momento, para garantizar la calidad del proyecto, necesitamos refactorizar el proyecto.

"Podemos verificar y calificar de acuerdo con los módulos comerciales, colocar diferentes módulos comerciales en diferentes módulos y realizar la estructura entre cada negocio. También se basan en la biblioteca pública subyacente. Este es el concepto de modularidad , pero cuando se involucran varios módulos Cuando el mismo se alcanza la función, el acoplamiento del código aumentará. Por ejemplo, hay dos módulos que necesitan la función de reproducción de video. Si la reproducción de video se coloca en dos componentes, se producirá el problema de la duplicación de código y no se siente muy bueno para ponerlo en la biblioteca pública. En este momento se utiliza la componenteización para resolver este problema

Modular y por componentes

modular

Módulos comerciales específicos, como el módulo de detalles del producto, el módulo de lanzamiento del producto, el módulo de búsqueda

en componentes

Un solo componente funcional, como el componente de reproducción de video, el componente para compartir, etc., cada componente se puede desarrollar como un módulo separado y se puede extraer por separado como un SDK para su lanzamiento externo.

La idea de la modularización y la creación de componentes es la misma, ambas son división de código, pero la modularización se basa en módulos funcionales (orientados a los negocios) y la creación de componentes se basa en módulos funcionales (orientados a funciones) y partículas modulares. es más grande, y la granularidad de los componentes es más pequeña.También es común que los módulos y los componentes coexistan en un proyecto, y cada uno es responsable de sus propios asuntos.

image

imagen

Como se muestra en la figura anterior, es la estructura básica de un proyecto en componentes

  • Biblioteca básica y biblioteca pública : clases de operación básica, clases de herramientas, introducción y empaquetado de bibliotecas de terceros, funciones de alojamiento de aplicaciones, módulos y componentes requeridos por el proyecto dependen de esta biblioteca
  • 组件层:项目用的功能模块或者业务模块,如:登录模块,视频播放组件,分享组件等
  • 应用层:宿主工程,APP的主项目,APP入口和主架子

组件化Demo

地址如下: github.com/syg13579/as… 我根据demo项目从以下几个方面来讲解

  • 1:项目分析
  • 2:组件application和library动态切换
  • 3:组件间的数据传递和方法调用
  • 4:组件类(例如:Fragment)的获取,以及夸组件页面跳转和通讯

1:项目分析

image

image

如上图所示,项目的主要结构

  • 应用层:app 项目的主入口
  • 组件层:goods login 商品详情页和登录组件
  • 基础库层:assemblebase用来各个组件数据和方法交互的 ,base是常用的工具类,各种类库的封装

2:组件application和library动态切换

在开发过程中,为了能够实现快速开发,组件能够独立运行就显的特别重要,moudle一般分为两种

  • App 插件,id: com.android.application
  • Library 插件,id: com.android.library

我们可以通过配置可动态进行application和library的切换,我们在各个组件的gradle.properties文件中配置一个控制切换的变量

image

image

然后在build.gradle中就可以通过isRunAlone变量来进行application和library的切换了,主要设计的点有三部分

  • plugin属性的配置
  • applicationId的配置
  • AndroidManifest的配置
if (isRunAlone.toBoolean()) {
    apply plugin: 'com.android.application'
} else {
    apply plugin: 'com.android.library'
}

android {
    compileSdkVersion 26

    defaultConfig {
        if (isRunAlone.toBoolean()) {
            applicationId "ppzh.jd.com.goods"
        }
        minSdkVersion 15
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

    sourceSets {
        main {
            if (isRunAlone.toBoolean()) {
                manifest.srcFile 'src/main/manifest/AndroidManifest.xml'
            } else {
                manifest.srcFile 'src/main/AndroidManifest.xml'
            }
        }
    }

}
复制代码

如果以上配置就可以实现application和library的切换了

3:组件间的数据传递和方法调用

由于主项目、组件之间,组件和组件之间不能直接通过引用进行数据传递和方法调用,那么在开发的过程中怎么进行数据传递和方法调用呢,可以通过「接口」+「实现」的方式进行,

assemblebase基础库就是用来进行数据传递和方法调用的,它被所有组件所依赖,assemblebase提供各个组件对外提供数据和方法调用的抽象service ,同时还有serviceFactory对service进行操作,各个组件在初始化的时候对各自的service进行实现。同时中也会提供所有的 Service 的空实现,以避免引起的空指针异常

就以登录模块为例,对外提供两个数据

public interface ILoginService {

    /**
     * 是否已经登录
     *
     * @return
     */
    boolean isLogin();

    /**
     * 获取登录用户的 AccountId
     *
     * @return
     */
    String getAccountId();

}
复制代码

相关的serviceFactory类如下,可以通过serviceFactory拉取相关service的实例

public class ServiceFactory {

    private ILoginService loginService;
    private IGoodsService goodsService;

    /**
     * 禁止外部创建 ServiceFactory 对象
     */
    private ServiceFactory() {
    }

    /**
     * 通过静态内部类方式实现 ServiceFactory 的单例
     */
    public static ServiceFactory getInstance() {
        return Inner.serviceFactory;
    }

    private static class Inner {
        private static ServiceFactory serviceFactory = new ServiceFactory();
    }

//    ------------------------LoginService------------------------
    /**
     * 接收 Login 组件实现的 Service 实例
     */
    public void setLoginService(ILoginService loginService) {
        this.loginService = loginService;
    }

    /**
     * 返回 Login 组件的 Service 实例
     */
    public ILoginService getLoginService() {
        if (loginService == null) {
            loginService = new EmptyLoginService();
        }
        return loginService;
    }
复制代码

在login组件中只需要实现ILoginService,并通过serviceFactory进行设置

public class LoginService implements ILoginService {
    @Override
    public boolean isLogin() {
        return false;
    }

    @Override
    public String getAccountId() {
        return null;
    }
}
复制代码

在login的appliction中进行service的设置

public class LoginApp extends BaseApp {

    @Override
    public void onCreate() {
        super.onCreate();
        initModuleApp(this);
        initModuleData(this);
    }

    @Override
    public void initModuleApp(Application application) {
        ServiceFactory.getInstance().setLoginService(new LoginService());
    }

    @Override
    public void initModuleData(Application application) {

    }
}
复制代码

但是有这样一个问题:在集成到app中,LoginApp是没有被执行的,这个怎么解决呢,我们可以通过反射进行解决

public class AssembleApplication extends BaseApp {
    @Override
    public void onCreate() {
        super.onCreate();
        initModuleApp(this);
        initModuleData(this);
        initComponentList();
    }

    @Override
    public void initModuleApp(Application application) {

    }

    @Override
    public void initModuleData(Application application) {

    }

    //初始化组件
    //通过反射初始化
    private void initComponentList(){
        for (String moduleApp : AppConfig.moduleApps) {
            try {
                Class clazz = Class.forName(moduleApp);
                BaseApp baseApp = (BaseApp) clazz.newInstance();
                baseApp.initModuleApp(this);
                baseApp.initModuleData(this);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

}
复制代码

如上所示就完成了

4:组件类(例如:Fragment)的获取,以及夸组件页面跳转和通讯

fragment的获取也是通过service来完成的

public interface IGoodsService {

    /**
     * 创建 GoodsFragment
     * @param bundle
     * @return
     */
    Fragment newGoodsFragment(Bundle bundle);
}
复制代码

相关组件实现该接口就行

各个组件间页面的跳转可以通过阿里的ARouter实现,我是通过设置ComponentName来实现的,但这种方式好像并没有实现真正的代码隔离

 /**
     *
     * 去登陆
     *
     * 跨组件页面跳转
     */
    private void toLogin(){
        Intent intent = new Intent();
        intent.setComponent(new ComponentName(mContext, "ppzh.jd.com.login.LoginActivity"));
        startActivityForResult(intent,LOGIN_REQUEST_CODE);
    }
复制代码

总结

通过上面就整体实现了项目组件化,在以后也可以更多的运用组件化来进行项目开发

本博主会持续更新Android学习知识,更多学习知识以及笔记请查看我的Gitee.

Supongo que te gusta

Origin juejin.im/post/6988015894119055367
Recomendado
Clasificación