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

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原生混合式开发的能力.
先上布局吧


<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>

添加使用网络权限

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

代码

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");
}

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");
}

这样再使用,那么就调用的是自己的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信息";
    }
}

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);

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

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

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

你可能感兴趣的:(移动开发)