Giter Site home page Giter Site logo

hybridfoundation's Introduction

前言

这里我整理了Android端会用到代码,包含JS通信,文件处理工具类,闪屏辅助类和WebView的封装。由于源码并没有完善,所以暂时没有发布到Maven仓库

用法

JS通信

  • 需要把libraryassets文件夹下的DeviceBridge.js放入并加载到你的前端项目中
  • Android调用JS 首先在JS中注册对应Handler,以注册的字符串为key对应
window.DeviceJsBridge.registMessageHandler("testCallJs", function (message, responseCallback) {
        alert("android调用js方法,消息内容:" + JSON.stringify(message))
        message.data = '我是在js中赋值的数据'
        responseCallback(message);
    });

然后就可以在Android代码中调用了

Message message = new Message();
message.setHandlerName("testCallJs");
message.setData("数据内容(onPageFinished执行android调用js,js返回的数据会打印在logcat)");
webView.getJsBridge().sendMessage(message, responseMessage ->
        System.out.println("js异步response消息:" + responseMessage));
  • JS调用Android 同样首先需要在Android中注册对应Handler,以注册的字符串为key对应
jsBridge.registMessageHandler("connectBluetooth", messageHandler);

然后就可以在JS中调用了

var message = {handlerName: 'testAndroid'}
var result = window.DeviceJsBridge.sendMessage(message, function (message) {
    alert("js调用android异步方法Response结果:" + JSON.stringify(message))
})

文件处理工具

相关用法详见代码注释,包含对压缩文件的处理

闪屏辅助类

下面列一下常用的方法

/**
 * 设置闪屏等待时间,最终等待时间和setDelayObservable共同决定
 */
public void setDelayTime(long delayTime)

/**
 * 设置闪屏等待Observable 最终等待时间和setDelayTime共同决定
 */
public void setDelayObservable(Observable<?> delayObservable)

/**
 * 设置闪屏隐藏监听
 */
public void setSplashHideListener(SplashHideListener splashHideListener)

/**
 * 展示闪屏
 *
 * @param viewId         包含Fragment的view id
 * @param splashFragment 闪屏Fragment
 */
public void showSplash(int viewId, Fragment splashFragment)

HybridWebView的封装

主要封装了通用的方法,对外提供了必要的监听回调,还包括了JSBridge的使用,让你在使用WebView的时候更方便,具体使用详见Demo

概述

移动开发的跨平台与快速发布一直是开发者的追求,也是技术的一个发展趋势,现在各大厂开始有了自己的大前端团队,所以我们也开始了自己的探索,目前来说主要有两种思路:

  • Hybrid App 代表:Cordova 通过Webview加载Web页面,在NativeWeb页面之间建立双向通信
  • H5代码Native化 代表:ReactNative,Weex等 使用各平台Api,把H5代码编译成二进制代码直接运行

其实关于这两种思路对比,网上有很多大牛分析的很全面了,总结来说各有利弊很难完美,本篇文章我们主要讲一下Hybrid App实践,采用前后端分离以及单页应用技术开发Web页面,使用WebView加载Web页面,并通过JS通信提供一些Native层的支持,通过接口获取更新后的差异化页面资源文件,在本地覆盖,就可以达到热更新的需求。在我看来此方案更适用于需要快速发布、多端兼容、对性能要求稍低的业务,正好符合我们的需求。

方案详解

既然确定了方向,那么就应该确定具体的方案了,通过自己的经验和网上资料整理,画了时序图: image

按照图上的时序,接下来说一下每一步中的实践,以及碰到的坑。下面讲解

初次安装

  • 打包 在打包程序时这一步主要是把Html相关资源文件压缩后放在assets文件夹下即可
  • 安装 用户安装完应用程序打开后,检测是否为初次使用,如果是则通过程序直接解压包内资源到手机存储上即可,不局限于SD卡。

展示页面

  • 闪屏页展示 由于上面的解压资源,还有Webview初始化、JS的加载执行、html的渲染都是耗时操作,并且都是发生在Html展示之前,所以我们选择把闪屏页用Android原生代码来编写,采用覆盖WebView所在Activity的方案,这样在闪屏页隐藏的时候,用户就可以看到业务界面,可以提升用户体验。 注:另外提供两种闪屏优化的小技巧,使用透明主题或者设置主题背景图片

  • 加载本地Html页面 直接使用WebView#loadUrl()加载本地资源文件即可。由于WebView加载不同页面会出现闪屏的问题,所以我们采用Vue + Vue Router构建单页应用即可。 这里Vue Router会有一个小坑,提醒大家注意一下:Vue Router默认采用hash模式,会有一个丑陋的#符号,作为一个有追求的程序员怎么能允许这种很丑的hash,一种更优雅的方式使用HTML5 History模式,但是不幸的是,加载本地资源文件的方式并不能正常解析HTML5 History模式的url,所以只能采用hash模式。

  • 数据请求 为了节省用户的流量和时间,需要把Html资源文件存储在本地,这样数据的请求必须在客户端完成。有两种方案供选择: 一是Native层拦截并请求数据再返回给Html层去展示,有我们采用前后端分离直接通过JS请求接口获取数据即可,这样会增加工作量,也不利于职责的分离,所以放弃。 二是直接使用JS请求数据,这样会出现跨域访问的问题,相比较来说还是这个比较容易解决的,采用CORS即可

  • Native调用JS Native层调用JS比较简单,执行一段JS代码即可,如:javascript:callJS()

  • JS调用Native JS层调用Native主要分为三种: 一:通过WebView#addJavascriptInterface()进行映射,使用起来简单,但是有安全风险,弃用 二:自定义协议然后由Native层拦截并解析请求,使用起来复杂,容易和业务耦合,也不是最优选,弃用 三:拦截JS#prompt()方法并解析,使用起来复杂,但是比第一种更安全,比第二种灵活一些,所以使用此方案

资源文件获取

资源文件采取差异化更新方案,本地存储一个标识,可以为版本号或者更新时间,这个可以和后端同学一起商量确定,资源文件下载还有推送之类的由于Html的局限性,所以还是直接由Native层做比较合适,下面简单讲解下应用中的两种更新方式:

  • 服务端推送下发 可以通过集成第三方的推送服务,在客户端收到更新推送后主动去请求下载差异化文件
  • 主动请求 可以在选择合适的时机,如在应用启动时去请求差异化文件

资源文件更新

根据差异化清单对资源文件进行整合,存放在临时目录中,然后在第二次打开应用时更换,并展示更新后的界面,达到热更新的效果。

总结

只是概括的讲了结构的内容,可能会遗漏一些要点,如果大家有什么问题欢迎提交issue

hybridfoundation's People

Contributors

free46000 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

hybridfoundation's Issues

SplashFragment_.builder().build()

  1. SplashFragment_.builder().build()
    can not resolve symbol "SplashFragment_."( SplashFragment_. 这个在代码中标红,并且找不到)
    2 Manifest.xml里面的
    MainActivity_" 也报红找不到,需要新建
    这是怎么回事?谢谢~

不能implements吗

不能implements吗,你的demo我run的时候报错解决不了
Unable to find method 'org.gradle.api.tasks.compile.CompileOptions.getBootClasspath()Ljava/lang/String;'.

关于splash解决白屏问题的一点意见

其实很早就下了代码了,最近也有时间看了下
首先呢,我现在做的项目也有很多动态更新的,跳转到Activity界面,这中间大概有2秒的白屏时间

我自己实际测试,解压代码并不需要多少时间,反而是webview的渲染,这里才是大头,所以我觉得只要监听webview加载完就隐藏Fragment即可,不需要那么复杂的设置延时,什么的吧。
监听:


   mWebview.setWebChromeClient(new WebChromeClient(){
      @Override public void onProgressChanged(WebView mWebView, int num) {
        super.onProgressChanged(mWebView, num);
        if (100==num){
          hideTranstion();
        }
      }
    });

PS:我很久没用RXjava了,所以不知道理解你代码中的Splash处理有不有错

当然楼主的使用fragment显示页面这个ideal很赞.

当然其实你可以看看Cordova中的处理,很健全,因为我现在项目用的是ionic,所以基本使用他来加载的

最后,谢谢你的分享,对于H5的差异化区别,然后下载新编写即可,我也准备研究,不知道能不能分享一下

Update on other resources

1.例如图片的请求。或者是css的请求。通过加载本地HTML只能解决部分问题。所以应该好需要h5页面中请求的拦截。

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.