前言
为什么要封装
——封装代码的主要目的是屏蔽代码的复杂度,提升代码的可阅读性。
原先的WebActivity都是根据功能模块不同而新建不同的Activity,且之间没有一个统一的BaseWebActivity进行控制,使得代码出现极高的重复,如果功能需要统一修改时,重复的代码会导致极高的维护成本。
所以我们需要将功能相似的代码进行封装,减少重复代码。如果将所有Web页面交给一个WebActivity控制
原项目中WebActivity的类(项目结构):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15com.xxx.web
--class CantBackWebView{}
--class CustomerServiceWebView{}
--class DefaultWebView{}
--class HealthAssessmentWebView{}
--class HealthBodyCheck2WebView{}
--class HealthBodyCheckWebView{}
--class HealthEncyclopediaWebView{}
--class HealthFileWebView{}
--class HealthInfoWebView{}
--class OrederWebView{}
--class QuestionWebView{}
--class RegistrationWebView{}
--class ReportQueryWebView{}
--class WxPayWebView{}如果仅仅是把这些WebActivity都交给同一个WebActivity控制行不行?
WebView中不止有定位、获取图片等通用功能,还有不同的evaluateJavascript
和@JavascriptInterface
等交互方法,H5与Android代码的耦合度很高,如果轻易把他们杂糅在一起,代码会十分的臃肿。
而这臃肿的代码放在同一个页面,其必将导致逻辑的最终混乱,这是毋庸置疑的。所以有如下认识:封装可能不会让你的代码更少(甚至更多),但必然更整洁、清晰,更方便调用。
内容
简述
- 创建这个项目是为了让WebActivit的书写简化,并增强代码逻辑性和易读性
- 我希望这是一个具有普适性的项目,而不是仅为了当前项目而去实现它
项目结构
1 | com.yooking.webviewutils |
LoadingCallback
、LocationCallback
、PermissionCallback
为interface
类- LoadingCallback负责项目核心逻辑回调
- LocationCallback负责项目定位逻辑回调
- PermissionCallback负责项目权限逻辑回调
BaseWebView
、ImageWebView
、LocationWebView
为abstract
类- 余者为工具类
走进项目
先来看逻辑类:
LocationWebView.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14/**
* 定位逻辑
* create by yooking on 2019/4/24
*/
public abstract class LocationWebView{
private static final String PERMISSION_LOCATION = "android.permission.ACCESS_FINE_LOCATION";
public abstract void checkPermission(PermissionCallback callback);
public abstract void checkLocation(LocationCallback callback);
public void startLocation(){...}
}总共三个方法:
权限判定
checkPermission
:abstract方法,继承者必须实现定位判定
checkLocation
:同上开启定位
startLocation
:定位逻辑1
2
3
4
5
6
7
8
9public void startLocation(){
checkPermission(new PermissionCallback(){
public void allowPermission(String... permissions){...}
public void refusePermissions(){}
});
}
当用户允许定位权限时调用
checkLocation
方法进行定位ImageWebView
与LocationWebView
一致
在BaseWebView
中如何使用这两个abstract类呢?
答案是使用多继承方案,请看1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17/*多继承组件 —— 定位组件*/
private class Location extends LocationWebView{
public void checkPermission(PermissionCallback callback){
checkLocationPermission(callback);
}
public void checkLocation(LocationCallback callback){
BaseWebView.this.checkLocation(callback);
}
public void startLocation(){
super.startLocation();
}
}
在
BaseWebView
中新建内部类,内部类重写LocationWebView
中的方法,该方法调用BaseWebView中相应的方法,如:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16/**
* 授权定位权限
*/
public abstract void checkLocationgPermission(PermissionCallback callback);
/**
* 定位功能实现
*/
public abstract void checkLocation(LocationCallback callback);
/**
* H5调用定位功能
*/
public void startLocation(){
new Location().startLocation();
}
至此
BaseWebView
中关于定位功能的封装完毕
同理可得ImageWebView
的封装
当然,在BaseWebView中也封装了诸如报错回调、基础WebSettings设定等……
接下来自然是工具类了GPSUtil
: 这个工具类封装了坐标系的转换,这里就不一一赘述了ImageChooser
: 这个工具类封装了打开相机/相册的方法1
2
3void goPhotoAlbum(){} //激活相册
void goCamera(String appId){} //激活相机
//在onActivityResult中的onActivityResult(int requestCode, int resultCode, Intent data)回调
实战使用
继承BaseWebActivity,重写方法如下:
1
2
3
4
5
6
7
8//设置contentView setContentView():void
//获取WebView的Id getWebViewId():int
//用于处理View initView():void
// loadingListener():LoadingCallback
//用于处理定位权限问题 checkLocationPermission(permissionCallback:PermissionCallback):void
//用于处理定位的获取 checkLocation(locationCallback:LocationCallback):void
//用于处理相机权限问题 checkPhotoPermission(permissionCallback:PermissionCallback):void
//用于处理相机的启用 takePhoto:void
LoadingListener
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31public interface LoadingCallback{
/**
* 监测web页面的title标签变化
*/
void titleChanged(String title);
/**
* 使用自定义协议的处理方法
*/
void diyScheme(Uri uri);
/**
* H5页面报错的处理方法
*/
void hasError();
/**
* 加载成功时的回调
*/
void isLoadSuccess();
/**
* 页面未开启前的回调
*/
void onPageStart();
/**
* 页面渲染结束的回调
*/
void onPageFinish();
}
如果引用了工具类中的打开相机方法,需要新建一个FileProvider
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15<manifest>
<application>
...
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:exported="false"
android:grantUriPermission="truee">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths"/>
</provider>
...
</application>
</manifest>
项目地址
项目地址:https://
代码乱写,文章一般,谢谢耐心观看,希望能对你有所启发