Android混合开发的入门和方案 您所在的位置:网站首页 安卓混合开发技术 Android混合开发的入门和方案

Android混合开发的入门和方案

2023-09-01 06:33| 来源: 网络整理| 查看: 265

前言

其实之前一直都很抵制hybrid开发,因为作为一个Android开发程序员,总是觉得原生的更好(其实是不想丢饭碗),但是一个闲着没事干,就写了一个demo搭了个webview,然后把html文件放到asset下面,一加载惊呆宝宝了,简直跟原生的没有区别啊,体验跟原生基本一样(andrid 5.0以后webview的速度比之前的版本有很大的提升),至此我就走上了学习混合开发的道路.

前期准备 WebView

其实我相信很多跟我一样刚入门混合开发的人,对于应该要学习哪部分知识都会感到迷惑,在这里我先谈谈我的经验:

html基础,不用说很厉害,但是至少你要知道整个html的体系还有css,div等控件的使用,还有对html节点的一些基本操作javaScript基础,这里说的基础就是语法之类的,js这一部分其实挺重要的,跟上面一样,但是js你懂得越多,少走的坑也就真的越少,切身体会啊!!!对一些常见的前段框架的运用,比如jquery,sui-mobile,第三点倒不是很重要webview的原理,这一点挺重要的,因为它涉及到webview中的js怎么去与android的native交互的原理,懂得原理你可以在混合开发中更加”自由地”做出你想要的东西 把网页搬到自己的app上面

假如我们的第一个需求是:把一个网页搬到自己的app上面。那此时,我们只需要下面这段代码就行

public class BolgActivity extends AppCompatActivity { private WebView webView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_bolg); webView = (WebView) findViewById(R.id.webview); //这段代码的作用是让webview不要使用系统自带浏览器 webView.setWebViewClient(new WebViewClient(){ @Override public boolean shouldOverrideUrlLoading(WebView view, String url){ return false; } }); webView.loadUrl("http://www.baidu.com"); } }

运行结果: 图片名称 在一般情况下,我们的做法都是把html文件放在app的asset目录下,然后通过下面的代码来加载html文件,这样大大提高了加载速度

mWebView.loadUrl("file:///android_asset/index.html"); native提供帮助

很明显这不能满足我们的需求,这样你的应用和浏览器又有什么区别,那现在我们提高要求。假如现在我们有一个新的需求: 要求网页弹出一个加载框(要求不是网页的加载框,而是android系统原生的加载框) 在完成这个需求之前,就必须先讲讲webview中的页面怎么去和android原生交互了.我们可以先把webview想象成一个容器,那么html页面就是运行在这个容器上面的. 那么我们的webview想要去调用html页面里的js就通过下面这段代码

webView.loadUrl("javascript: log()");

那么js中要调用android里面的代码就是通过webview注入一个对象,然后让js调用,下面我用伪代码表示一下:

{ //假设这里是activity里面 webView.addJavascriptInterface(new JsInterface(), "interface"); class JsInterface{ void showToast(String msg){ Toast.make(MainActivity.this, toast, Toast.LENGTH_SHORT).show(); } } } ------------------------------------------------------- { //假设这里是在一段JavaScript函数里面 interface.showToast("I'm js"); }

上面讲的是第一种js和native交互的方式,其实我说的很直白,如果看不懂可以看看下面这篇博文: js与webview的交互(并不是很喜欢这种转载的,但由于原创的那篇打不开,将就一下吧)

进阶 JsBridge

ps:上面我们讲了js与native交互的一种方案,但在实际运用中我发现并不是很好用,js与native的调用一多,会显得代码非常混乱,当然后面也有个方案能解决,甚至比我接下来要讲的方案还要好,这里先讲下我现在在使用的方案。 相信我的这篇blog是你查阅了大量资料以后才无意中看到的,那么你肯定是知道JsBridge了。先看看代码

{ //这是在native中的代码,mWebView为JsBridge封装过的webview mWebView.callHandler("myInit", "我是数据", new CallBackFunction() { @Override public void onCallBack(String data) { } }); } ----------------------------------------------------------------------------------------------------- { //这是在Js中的代码,bridge是native注入在js中的对象 bridge.registerHandler("functionInJs", function(data, responseCallback) { document.getElementById("content").innerHTML = ("data from Java: = " + data); var responseData = "Javascript Says 我要你的地址!"; responseCallback(responseData); }); }

上面这段代码什么意思呢?就是在js中通过bridge注册一个函数,然后在native中通过封装好的webview.callHandler函数来调用js中已经注册好的函数,那么反过来Js想调用native的函数,也是同样的道理,只要在native中注册好函数,在js中通过bridge.callHandler来调用就行了。 这样给我们的开发提供了极大的方便,而且避免了很多代码混乱的情况,那么它的基本原理是什么呢?下面我还是用最简单地语言来讲一讲。

在我们的webview中,可以设置自定义的WebChromeClient,这个东西就是加载在webview中的html中有弹窗事件的时候会回调的WebChromeClient里面有很多种回调,其中有一个回调方法onJsPrompt,这个方法就是我们的突入点(其他方法也都可以,但是可能会干扰到原来的逻辑,这个比较少用,所以我们用这个)

语言是不是很简单暴力?如果你还看不懂,看看下面的实例:

{ //假设这里是在js里面 var uri = "hybrid://objectName:sid/methodName?params"; var value = "xxxxxxx"; window.prompt(uri, value); } -------------------------------------------------------------- { //这是在activity里面 public class InjectedChromeClient extends WebChromeClient { @Override public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) { //这里传进来的参数就是从js的window.prompt(uri, value)传过来的参数 return super.onJsPrompt(view, url, message, defaultValue, result); } } }

JsBridge的工作原理就是这样,那么现在看来好像对我们没什么用呀?下面我举个实际应用的例子说一下,就拿上面那个例子来说:要求网页弹出一个加载框(要求不是网页的加载框,而是android系统原生的加载框) (先不要讲太复杂的代码,从上面JsBridge的知识我们已经知道了js里面能传递数据给webview)

{ //假设这个方法是js中负责发送数据给webview的 function postToNative(data){..省略..} var data = { "tagName":"showLoadingDialog", "pars":{ "content":"正在加载中", "title":"请等待", //这个callback就是当加载框被取消的时候native回调js中的函数 "callback":"onLoadingCancel" } }; postToNative(data); } { //假设这个方法实在native中接收webview中的js发过来的数据 void receiveJsData(String data){ //上面js的函数可以看出,js向我们发送了一段json数据 //所以我们只需解析这段数据,便可知道js需要native做什么事 } } 总结 对比

觉得上面讲的都是废话? 其实网上关于hybrid开发的文章我敢说我基本都看过了,国外的文章也有看了看,在实际开发中,我自己也写了很多demo,下面是我总结的关于一些JsBridge的优缺点: 优点:

相比传统的方式方便很多,代码更加简洁其实第一点已经完爆一切了,写不出第二点了哈哈

缺点: 1. 调试困难,不知是否是博主基础太差,过程中有许多意料不到的错(当然是关于js的),不过到后面基本都能解决了 2. 如果要做到一个页面可以兼容所有web页面,那需要注册的函数太多了,因为每个页面需要的功能都不一样 3. 生命周期有点难掌控,假如你在JsBridge未初始化之前就调用,那么会导致JsBridge初始化失败(之前这个坑陷了好久后面才发现的)

实际应用

在实际开发中,我的方法是通过json来灵活地定义每个动作,也就是利用json数据,来告诉native我需要做什么动作。通过这种方式,一个app甚至只要一个activity就能解决所有的页面,此时有人要问了,那我每个页面的ui就都一样了吗?比如说toolbar,alertDialog。 然而并不是这样的,通过我上面将的知识点,可以在js初始化的时候,定义一段json数据,用户初始化ui,例如下面的:

var data = { "title":"话题列表", "right":{ "icon":"R.mipmap.ic_launcher", "description":"描述", "callback":"onRightBtnClick" } };

然后在native中解析这段数据,来达到初始化ui的效果,这种方式我也已经运用在我的项目中。 相信你看了这边文章,你已经基本知道了webview在实际开发中的应用和各种方案,如果觉得文章有哪些地方写的不好,请留言说明。

ps:代码下次贴出,在写个几个基类供参考,写得还不是很完善,需要的也提出来把!



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有