最近在享学报了个vip课程,由于课程已经开始 所以第一节课从webview开始上 老师说是讲webview 其实讲了很多项目架构方面的东西 收获很多
老师通过google 的auto service 以及java 的serviceLoader架构进行组件化通信 感觉比Arouter简单好多 总结一下
最终的代码在https://github.com/Semon-Zhang/ProcessWebView
一个项目的大体结构 应该模块化 层次化 组件化 控件化 大体应该是这样的
base 层放的是一些架构层的公共方法(老师说架构师才能改)我认为一般是一些项目通用的方法简单点说就是可以直接抽出来挪到新的项目里用 与业务逻辑无关的代码
network 层封装网络请求 不解释 我自己项目用的retrofit封装在了base 理论上讲应该是要单独抽取出来的
common层 我认为是封装业务逻辑相关的通用代码 比如组件间通信用到的接口 业务数据catch 数据库
组件 具体的业务逻辑实现 自定义的一些界面 例如我们要做的webview
下面我们开始写代码
首先我们新建三个module base common webview common 引用base webview 引用common app里引用webview module
webview中我们添加一个WebActivity 布局文件中 添加一个webview 在activity里加载一个百度
这里 我们使用dataBinding 来查找控件 首先在module_webview build.gradle 里 android下 添加dataBinding { enabled true }
布局文件中根标签使用
这样会生成一个ActivityWebBinding 这个名字是由于我的布局文件名字是activity_web
这样在activity可以通过DataBindingUtil.setContentView() 传入Activity 以及布局文件id 得到ActivityWebBinding 对象 通过ActivityWebBinding.控件id 就可以直接得到控件 比以前的查找方式方便很多
随后我们如果在app里直接跳转WebActivity 应该就可以展示出百度的界面了
这里有三个坑 一是 如果百度链接写成 http://www.baidu.com/ 的话 在manifest application 节点下必须配置 android:usesCleartextTraffic="true"支持http
二是 manifest里要添加网络权限 三是 app的 build.gradle 里 android下也要 添加dataBinding { enabled true } 不然会导致界面显示不出 甚至闪退
接下来 我们在common 里定义一个IWebViewService 接口 里面有一个startWebViewActivity 方法 启动WebActivity
里面可以添加一些参数 例如加载的网页链接 添加一个标题等等
然后回到module_webview 添加一个WebViewServiceImpl 类 实现IWebViewService 接口 在startWebViewActivity 里启动WebActivity 并且把方法的参数传递给WebActivity
重点来了 我们需要在 module_webview引入com.google.auto.service:auto-service:1.0-rc7 AutoService库 同时 这里我们要在接口的实现类上添加注解@AutoService({IWebViewService.class})
表明这个类是IWebViewService 接口的实现类
接下来 我们要从app里跳转到WebActivity 在之前 我们通过 MainActivity.this.startActivity(new Intent(MainActivity.this, WebActivity.class)); 跳转
现在我们有了新的方法 ServiceLoader 我们通过 ServiceLoader.load(IWebViewService.class) 可以拿到IWebViewService的实例 由于接口的实现类可能有很多
所以我们要通过iterator.next 来获得WebViewServiceImpl 实例 这么做是因为在一般的业务逻辑中 相同的业务通常只有一个实现
在获得到IWebViewService的实例也就是WebViewServiceImpl 之后就可以通过调用startWebViewActivity方法就可以实现跳转到webview module里的界面了
当然 出于架构师的执着 我们的ServiceLoader 可以放在base里 通过泛型方法来获得 我们的接口实例(写了这么久终于用到了base)
于是 完整的 app里跳转就变成了
我们可以通过调用startWebViewActivity 来启动WebActivity 同时可以给WebActivity 传参数来控制 WebActivity里面的界面显示 (具体实现就不再写了)