0%

Andorid封装之WebActivity

前言

  1. 为什么要封装

    ——封装代码的主要目的是屏蔽代码的复杂度,提升代码的可阅读性。
    原先的WebActivity都是根据功能模块不同而新建不同的Activity,且之间没有一个统一的BaseWebActivity进行控制,使得代码出现极高的重复,如果功能需要统一修改时,重复的代码会导致极高的维护成本。
    所以我们需要将功能相似的代码进行封装,减少重复代码。

  2. 如果将所有Web页面交给一个WebActivity控制

    原项目中WebActivity的类(项目结构):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    com.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代码的耦合度很高,如果轻易把他们杂糅在一起,代码会十分的臃肿。
    而这臃肿的代码放在同一个页面,其必将导致逻辑的最终混乱,这是毋庸置疑的。

  3. 所以有如下认识:封装可能不会让你的代码更少(甚至更多),但必然更整洁、清晰,更方便调用。

内容

简述

  • 创建这个项目是为了让WebActivit的书写简化,并增强代码逻辑性和易读性
  • 我希望这是一个具有普适性的项目,而不是仅为了当前项目而去实现它

项目结构

1
2
3
4
5
6
7
8
9
10
11
com.yooking.webviewutils
-class BaseWebView{}
-class ImageWebView{}
-class LocationWebView{}
-.callback
--interface LoadingCallback{}
--interface LocationCallback{}
--interface PermissionCallback{}
-.tools
--class GPSUtil{}
--class ImageChooser{}
  1. LoadingCallbackLocationCallbackPermissionCallbackinterface
    • LoadingCallback负责项目核心逻辑回调
    • LocationCallback负责项目定位逻辑回调
    • PermissionCallback负责项目权限逻辑回调
  2. BaseWebViewImageWebViewLocationWebViewabstract
  3. 余者为工具类

走进项目

  1. 先来看逻辑类: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(){...}
    }
  2. 总共三个方法:

    • 权限判定 checkPermission:abstract方法,继承者必须实现

    • 定位判定 checkLocation:同上

    • 开启定位 startLocation:定位逻辑

      1
      2
      3
      4
      5
      6
      7
      8
      9
      public void startLocation(){
      checkPermission(new PermissionCallback(){
      @Override
      public void allowPermission(String... permissions){...}

      @Override
      public void refusePermissions(){}
      });
      }
  3. 当用户允许定位权限时调用checkLocation方法进行定位
    ImageWebViewLocationWebView一致
    BaseWebView中如何使用这两个abstract类呢?
    答案是使用多继承方案,请看

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    /*多继承组件 —— 定位组件*/
    private class Location extends LocationWebView{
    @Override
    public void checkPermission(PermissionCallback callback){
    checkLocationPermission(callback);
    }

    @Override
    public void checkLocation(LocationCallback callback){
    BaseWebView.this.checkLocation(callback);
    }

    @Override
    public void startLocation(){
    super.startLocation();
    }
    }
  1. 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();
    }
  1. 至此BaseWebView中关于定位功能的封装完毕
    同理可得ImageWebView的封装
    当然,在BaseWebView中也封装了诸如报错回调、基础WebSettings设定等……
    接下来自然是工具类了
    GPSUtil : 这个工具类封装了坐标系的转换,这里就不一一赘述了
    ImageChooser : 这个工具类封装了打开相机/相册的方法

    1
    2
    3
    void goPhotoAlbum(){} //激活相册
    void goCamera(String appId){} //激活相机
    //在onActivityResult中的onActivityResult(int requestCode, int resultCode, Intent data)回调

实战使用

  1. 继承BaseWebActivity,重写方法如下:

    1
    2
    3
    4
    5
    6
    7
    8
    @Override setContentView():void //设置contentView
    @Override getWebViewId():int //获取WebView的Id
    @Override initView():void //用于处理View
    @Override loadingListener():LoadingCallback //
    @Override checkLocationPermission(permissionCallback:PermissionCallback):void //用于处理定位权限问题
    @Override checkLocation(locationCallback:LocationCallback):void //用于处理定位的获取
    @Override checkPhotoPermission(permissionCallback:PermissionCallback):void //用于处理相机权限问题
    @Override takePhoto:void //用于处理相机的启用
  1. 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
    31
    public interface LoadingCallback{
    /**
    * 监测web页面的title标签变化
    */
    void titleChanged(String title);

    /**
    * 使用自定义协议的处理方法
    */
    void diyScheme(Uri uri);

    /**
    * H5页面报错的处理方法
    */
    void hasError();

    /**
    * 加载成功时的回调
    */
    void isLoadSuccess();

    /**
    * 页面未开启前的回调
    */
    void onPageStart();

    /**
    * 页面渲染结束的回调
    */
    void onPageFinish();
    }
  1. 如果引用了工具类中的打开相机方法,需要新建一个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://
代码乱写,文章一般,谢谢耐心观看,希望能对你有所启发

------------本文结束感谢您的阅读------------

Thank you for your accept!