Html5 + android原生 混合式开发(一)

来源:互联网 发布:java初学者小项目源码 编辑:程序博客网 时间:2024/06/09 20:49

Html5 + android原生 混合式开发(一)


1.设计目的: 
好久不写博客了,现在写一写html + Android原生混合式开发吧. 
现在js写app主要的框架(不算国内)有两个,一个是cordova(phoneGap),另一个是React-native,但是由于我写的是android原生的混合开发,所以以上就都不考虑了. 
仿写网易客户端主要是我随便挑的,不过技术是通用的,如果你看明白了,自己写一个app也没有任何问题.

2.适用人群和涉及的技术要点(看不看不影响本文阅读): 
适合人群:本文适合有一定android开发基础,html和js的人群,仅供入门之用. 
手机html涉及到 flex 布局,我在网上找了一篇,肯定比我说的好,链接如下(http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html?utm_source=tuicool). 除了 flex 布局,诸位还可以配合 这篇文章进行观看 (使用Flexible实现手淘H5页面的终端适配 : http://www.w3cplus.com/mobile/lib-flexible-for-html5-layout.html) 
此外,还涉及到 android 与 js 的交互,这个主要就涉及到webview的应用.诸位可以在网上直接搜索相关主题,如果不明白,也不用急,稍后我将会进行讲解. 
最后,我认为,如果为了使app有更广大的用途,对Java,android的知识也必不可少.

3.开发环境: 
我使用的IDE有 android studio 2.1, webstorm 2016.1.1, 开发环境是 window 10, 测试环境 虚拟主机, 黑莓 priv, 小米4.

4.获取资源: 
4.1图片: 
现在的软件越来越大,其中一个重要的原因是: 图片制作越来越精良,也越来越多.要仿制一个软件,如果所需要的图标都自己制作,不仅耗时耗力,而且也很难完全一致,最好的方法就是从被仿制的软件直接获取. 
所以我就直接解压网易新闻官方apk获取到了相应的图片.由于我没有设计图,所以选取的图片可能并不会和客户端一致,是个小小的遗憾. 
4.2新闻内容: 
内容方面我们有两种选择,一种是仿造数据,二是获取原生数据.仿照数据最为简单,如果为了测试,那还好,但是作为一个身经百战的程序员,如果光仿造的话是无法知道其他人的思路的.这里提供一个思路,那就是抓包.网络抓包有很多种,考虑到客户端可以运行在本地虚拟机,而且新闻一般走的是http协议,不妨用 fiddler 抓包试试看. 
这里为了方便有些对抓包不是很了解的人,我在网上找了几篇文章,有兴趣的不妨观之. 
什么是抓包: http://baike.baidu.com/view/558624.htm 
如何对模拟器进行抓包: http://www.jianshu.com/p/7135afa4a828 
但是,由于我是在我个人电脑上进行抓包的(抓到的http协议数据并不完全),而获取https协议需要加载根证书,加之我以前有次在公司弄这个事情出了bug,所以我对本机很精神.于是对抓到包里的数据进行了搜索,找到了一个测试用的公开api,于是就是它了.参考如下: http://blog.csdn.net/modalyin/article/details/51509620

5.知识点先行讲解: 
先讲解一下webview及与js相互调用的知识,如果你已经完全掌握了该知识点,并有html相关知识.你就可以不用看剩下的文章,你已经完全具备了HTML5 + android原生混合式开发的能力. 
先上布局吧

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context=".Main">         <WebView        android:id="@+id/main_web"        android:layout_width="match_parent"        android:layout_height="match_parent">    </WebView>    </RelativeLayout>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

添加使用网络权限

<uses-permission android:name="android.permission.INTERNET"></uses-permission>
  • 1
  • 1

代码

protected void onCreate(Bundle savedInstanceState) {   super.onCreate(savedInstanceState);   requestWindowFeature(Window.FEATURE_NO_TITLE);   setContentView(R.layout.activity_main);   mWeb = (WebView)findViewById(R.id.main_web);   mWeb.getSettings().setJavaScriptEnabled(true);   mWeb.loadUrl("http://www.baidu.com");}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

mWeb是我们的webview控件.getSettings().setJavaScriptEnabled(true)是启用了JavaScript. mWeb.loadUrl是指明要连接的地址,注意:参数中要写清楚协议.点击运行,链接到了百度,但却是调用了外部的默认浏览器,而不是我们的webview控件.所以这时我们需要指明调用的自己的控件,所以代码需要改成

protected void onCreate(Bundle savedInstanceState) {   super.onCreate(savedInstanceState);   requestWindowFeature(Window.FEATURE_NO_TITLE);   setContentView(R.layout.activity_main);   mWeb = (WebView)findViewById(R.id.main_web);   mWeb.getSettings().setJavaScriptEnabled(true);   //覆盖WebView默认使用第三方或系统默认浏览器打开网页的行为,使网页用WebView打开   mWeb.setWebViewClient(new WebViewClient(){        @Override        public boolean shouldOverrideUrlLoading(WebView view, String url) {            //返回值是true的时候控制去WebView打开,为false调用系统浏览器或第三方浏览器            view.loadUrl(url);            return true;        }   });   mWeb.loadUrl("http://www.baidu.com");}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

这样再使用,那么就调用的是自己的webview了.

js怎样和android交互呢?webview有一个方法 void addJavascriptInterface(Object obj, String interfaceName),obj是我们事先编写一个类,里面的方法可以供webview上网页上的js调用.然而在网页上我们需要知道如何调用obj对象.所以interfaceName就是js调用对象的名字,不过由于这段代码造成了一个安全漏洞,所以我们需要在obj里的方法上加上@JavascriptInterface注解(造成的漏洞可以参看http://blog.csdn.net/leehong2005/article/details/11808557). 
所以我们的代码再改成:

protected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    requestWindowFeature(Window.FEATURE_NO_TITLE);    setContentView(R.layout.activity_main);    mWeb = (WebView)findViewById(R.id.main_web);    mWeb.getSettings().setJavaScriptEnabled(true);    mWeb.addJavascriptInterface(new JSBridge(), "android");    mWeb.loadUrl("file:///android_asset/index.html");}public class JSBridge{    @JavascriptInterface    public String toast(string str) {        Toast.makeText(getApplicationContext(), "传入的参数是" + str, Toast.LENGTH_SHORT).show();        return "我是android信息";    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

mWeb.loadUrl(“file:///android_asset/index.html”);这里的”file:///android_asset/index.html”是我放在android上的html文件.

这里顺便说一下 android studio 下如何放置本地html文件: 
首先点击 File -> new -> Folder -> Assets Folder ,弹出选项对话框后点击默认选项就可以,然后你会在 app 下面看到一个 assets 文件夹,把我们事先写好的html文件拖过就可以了.这个 assets 文件夹下的html结构组织按照通常的组织就可以了,html调用其他文件夹里的文件或者资源写成相对路径就可以,并不需要修改路径.

JSBridge 是我们供js调用的对象,里面的方法的参数和返回值可以是任意的,里面的方法可以通过调用android原生方法来做我们想做的事情,然后我们只需要在html里这么调用就可以了

var in = "我是传入的参数";var result = android.toast(in); console.log(result);
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

当你的html执行这块代码时,会看到android手机上弹出一条toast,内容就是我们所希望的.

至于 android调用js的函数,非常简单,这么写就可以: 
mWeb.loadUrl(“javascript:jsconsole(“+”内容”+”)”); //jsconsole是js里的一个函数.

今天由于时间有限,暂时写到这里,后面我再有空陆续补完.

阅读全文
0 0