前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >组件化三问—字节真题

组件化三问—字节真题

作者头像
码上积木
发布2020-10-29 16:42:46
7280
发布2020-10-29 16:42:46
举报
文章被收录于专栏:码上积木

组件化由于它的解耦,独立,开发效率已经成为了被广泛使用的项目架构了,特别是大项目重构的首选,今天就一起来看看组件化开发。

  • 说说模块化和组件化
  • 说说组件间通信是怎么做的
  • Application生命周期分发是怎么做的

说说模块化和组件化

模块化也就是可以把app中的一些功能分成不同的模块,在Androidstudio里面以不同的module展示,然后模块之间会有相互依赖的关系,但是高耦合度就意味着虽然分成了不同的模块,但是还是一个整体的项目,拆分的意义就不大了。

所以这时候就需要对项目进行组件化,组件化的最大差别就是在于他的解耦,让每个模块可以独立作为app,模块之间没有直接的依赖关系,单独的基础模块可以供每个业务模块使用。这样带来的好处就是:

  • 加快了编译速度,每个业务功能都是单独的工程,可以独立编译
  • 提高协作效率,独立化使得每个组件的开发都相对独立,互不影响
  • 功能重用,组件化之后,以后做新项目就能很快开展起来,一些基础组件都可以直接用起来,比如网络组件等

说说组件间通信是怎么做的

  • 页面跳转的话,比如Activity,Fragment等跳转都是通过ARouter实现,ARouter是一种路由框架,之前的文章也讲过,通过apt生成pathactivity的关系代码,然后进行页面跳转。
  • 组件间通信的话,由于组件之前是没有耦合度的,所以需要单独新建一个组件用于暴露服务接口,然后两个需要通信的模块都依赖这个通信接口组件,一个实现所需要的服务接口,一个 去调用接口,这样就完成了通信。至于接口的实现注入还是有ARouter来完成。这样就在保证了组件之间无关联的前提下进行了通信。
  1. 接口组件module_export
代码语言:javascript
复制
public interface INewsService extends IProvider {
    NewsInfo getNews();
}

public class CartServiceUtil {

 public static INewsService getService(){
        return (INewsService) ARouter.getInstance().build("/news/service").navigation();
    }

    public static NewsInfo getNews(){
        return getService().getNews();
    }
}
  1. 通信组件module_news,实现接口
代码语言:javascript
复制

    //依赖接口组件
    implementation 'module_export'

@Route(path = "/news/service")
public class NewsServiceImpl implements INewsService {

    @Override
    public NewsInfo getNews() {
        //这里实际项目中 应该是 请求接口 或查询数据库
        NewsInfo newsInfo = new NewsInfo();
        return newsInfo;
    }

    @Override
    public void init(Context context) {
        //初始化工作,服务注入时会调用
    }
}

  1. 通信组件module_home,调用接口
代码语言:javascript
复制

    //依赖接口组件
    implementation 'module_export'

    CartServiceUtil.getNews()

Application生命周期分发是怎么做的

这个问题其实是问的,Application的生命周期管理肯定是放在主模块上的,比如onCreate,但是其他的业务模块也有需要在Application的生命周期中需要初始化的内容,而且由于解耦,业务模块和主模块是没有联系的,那么作为业务模块,该怎么获得Application生命周期呢?

第一个方法是通过反射,就是在主 模块中反射获取子模块的初始化对象,然后调用其初始化方法。

代码语言:javascript
复制
public static String[] moduleInits = {
            moduleOneInit,
            moduleTwoInit
    };

 public interface BaseAppInit {  
    boolean onInit(Application application);
 }private void initModuleHighPriority(){    
    for (String init: ModuleConfig.moduleInits){       
         try {            
        Class<?> clazz = Class.forName(init);            
        BaseAppInit appInit = (BaseAppInit) clazz.newInstance();            
        appInit.onInitHighPriority(this);        
        } 
        catch (ClassNotFoundException | IllegalAccessException | InstantiationException e)
         {           
         e.printStackTrace();       
         }    
 }}


虽然这样可以实现,但还是一个笨方法,因为还是要去获取业务模块的类名,而且反射毕竟效率很低,影响性能

其实我们可以借鉴Arouter的实现方式,通过apt,也就是注解处理工具,在编译期间去获取所有注解过的类,然后调用他们所实现接口的初始化方法。这里有个库大家可以借鉴下:https://github.com/hufeiyang/Android-AppLifecycleMgr

使用代码贴下:

代码语言:javascript
复制

@AppLifecycle
public class CartApplication implements IApplicationLifecycleCallbacks {

    public  Context context;

    /**
      * 用于设置优先级,即多个组件onCreate方法调用的优先顺序
      * @return
     */
    @Override
    public int getPriority() {
        return NORM_PRIORITY;
    }

    @Override
    public void onCreate(Context context) {
        //可在此处做初始化任务,相当于Application的onCreate方法
        this.context = context;

        Log.i("CartApplication", "onCreate");
    }

//...
}


//主工程 MyApplication
public class MyApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();
        ApplicationLifecycleManager.init();
        ApplicationLifecycleManager.onCreate(this);
    }

}

参考

https://juejin.im/post/6881116198889586701

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-10-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 码上积木 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 说说模块化和组件化
  • 说说组件间通信是怎么做的
  • Application生命周期分发是怎么做的
  • 参考
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档