Quantcast
Channel: CSDN博客移动开发推荐文章
Viewing all articles
Browse latest Browse all 5930

android web混合开发 混合开发实例——JS与Java的交互

$
0
0

今天说说安卓混合开发。 
曾经有一个话题是web终会一统app,然后我们看到随着时间的推移。web越来越强大(H5啊,js各种框架啊),但同时原生app也在不断发展。 
或许在将来还会再有这种话题论战,但目前,混合开发,结合web和原生app二者各自的优势,已经是众望所归了。

其中最常见的一种方式,在安卓的webview中嵌套web,通过各类设计,让二者进行交互。使得用户体验上几乎无法分辨出究竟是否纯原生。 
这种方式最值得深入研究的就是,安卓中的Java代码与web端的JavaScript代码进行相互交互调用。


简单介绍一下背景知识:(Java和javascript

说到java,作为目前(以及此前这么多年来)最受青睐最有用武之地的语言,就不多介绍了。贴百科: 
Java具有简单性、面向对象、分布式、健壮性、安全性、平台独立与可移植性、多线程、动态性等特点[2] 。Java可以编写桌面应用程序、Web应用程序、分布式系统和嵌入式系统应用程序等[3] 。

说到javascript。贴百科:JavaScript一种直译式脚本语言,是一种动态类型、弱类型、基于原型的语言,内置支持类型。它的解释器被称为JavaScript引擎,为浏览器的一部分,广泛用于客户端的脚本语言,最早是在HTML(标准通用标记语言下的一个应用)网页上使用,用来给HTML网页增加动态功能。

这么晦涩难懂? 那就简单一句话,其实java和JavaScript,完全是两码事。前者是面向对象,后者是内置对象。且后者借鉴了前者,但二者并没有关系.


好了,来到正题吧,先上效果图。

这里写图片描述

图中, 
上半部分(蓝色背景)是安卓中实现的简单布局 
下半部分(白色背景)是一个webview,里面的内容自然就是一个网页。

但是我们看到,点击上半部分安卓中的视图,能够改变webview中网页的视图。 
同样,点击下半部分网页中的Button,能够调用安卓的Toast对话框。

这就是简单的一个Android与web交互,目前在安卓界普遍称为JS交互


理论的东西讲完了,接下来上代码: 
今天的主角其实是两方面:安卓和web, 
但我们分为4个类: 
1.index.html,这是一个简单的web页面。 
2.activity_main.xml 安卓的布局 
3.MainActivity 安卓的主界面,同时也是本例的入口 
4.JsInterface,这个类其实算帮助类,只是为了代码好看才抽出来


1.首先是index.html: web的布局及函数 (注意,这个文件要放在安卓的assets文件下)

<html>
<!-- 简单写,就省略了head -->
<body>
    <script language="javascript">
        //这个方法是与java事先商定的方法,让java来调用
        function java_call_Js(param) {
            var x = document.getElementById('test');
            x.innerHTML = "Hello , New text form java ! ------------>" + param;
        }

        //Html自身Button的方法,去调用Java
        function btn_js() {
            jsInterface.js_call_java();
        }
    </script>

    <input type="button" onClick="btn_js()"
        style="height: 60px; width: 240px; margin-top: 40px ; margin-bottom: 10px"
        value="(JS call Java)I'm a Button in html">

    <div id="test">
        <font color="#FF0000">this is the old text</font>
    </div>
</body>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

2.其次是activity_main: 安卓的布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:background="#336699"
        android:gravity="center_vertical"
        android:orientation="vertical" >

        <EditText
            android:id="@+id/text_edit"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="请输入你想在html显示的数字(不输入参数会报空指针)"
            android:inputType="number"
            android:maxLength="7"
            android:textColor="#ffffff" />

        <Button
            android:id="@+id/btn_java"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="java call js(I&apos;m a Button in Android" />
    </LinearLayout>

    <WebView
        android:id="@+id/webview"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />

</LinearLayout>
  • 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
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 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
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37

3.其三是MainActivity: 主要的逻辑代码

public class MainActivity extends Activity {

    private EditText mEditText;
    private Button mButton;
    private WebView webview;
    private JsInterface jsInterface;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mEditText = (EditText) findViewById(R.id.text_edit);
        mButton = (Button) findViewById(R.id.btn_java);
        webview = (WebView) findViewById(R.id.webview);

        // 实例化接口JsInterface
        jsInterface = new JsInterface(webview);
        // 初始化WebSetting
        initWebSetting();

        webview.loadUrl("file:///android_asset/index.html");
    }

    @SuppressLint("SetJavaScriptEnabled")
    private void initWebSetting() {

        // 允许JS交互
        webview.getSettings().setJavaScriptEnabled(true);
        // 设置JS的接口
        webview.addJavascriptInterface(jsInterface, "jsInterface");

        webview.setWebViewClient(new WebViewClient() {
            @Override
            public void onPageFinished(WebView view, String url) {
                super.onPageFinished(view, url);
                mButton.setOnClickListener(new View.OnClickListener() {

                    @Override
                    public void onClick(View v) {
                        int param = Integer.parseInt(mEditText.getText().toString());
                        jsInterface.java_call_Js(param);
                        param = 0;
                    }
                });
            }
        });
    }
}
  • 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
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 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
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49

4.最后是JsInterface,封装了两个函数

//虽然命名为Interface,其实是伪接口,主要是为了方便理解及以后做抽象处理
public class JsInterface {
    private WebView mWebView;

    // 构造方法,传入一个参数WebView
    public JsInterface(WebView webView) {
        this.mWebView = webView;
    }

    // 这个方法是js调用java
    @JavascriptInterface
    public void js_call_java() {
        new Handler(Looper.getMainLooper()).post(new Runnable() {
            @Override
            public void run() {
                // 主线程更新UI
                Toast.makeText(mWebView.getContext(), "I'm a function in java", Toast.LENGTH_SHORT).show();
            }
        });
    }

    // 这个方法 是java调用js
    public void java_call_Js(int param) {
        // 这里调用html中的js代码的 java_call_Js 方法
        mWebView.loadUrl(String.format("javascript:java_call_Js(" + param + ")"));
    }
}
  • 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
  • 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

注释都有,就不多说了。

在模拟器上运行代码,就会看到如上的效果图 
这里主要看交互的双方(安卓和html): 
都保留着两个方法(一个用来被对方调用,一个去调用对方)。 
所有,做JS的前提是,要达成一种约定。要明确了对方的什么对象的什么方法可以被调用,才能如鱼得水。

另外这个地方值得注意:

        // 允许JS交互 ------>意味着可能会被JS注入等攻击,安全问题需要考虑//
        webview.getSettings().setJavaScriptEnabled(true);

        // 设置JS的接口--------->第二个参数"jsInterface" 定义了给html中使用的对象就叫jsInterface
        webview.addJavascriptInterface(jsInterface, "jsInterface")

        //html中使用这个对象的代码就是:   jsInterface.js_call_java();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

好了,大功告成,献上我的Demo源码: 
http://download.csdn.net/detail/lebang08/9656823

作者:mr_jianrong 发表于2017/6/22 13:44:46 原文链接
阅读:100 评论:0 查看评论

Viewing all articles
Browse latest Browse all 5930

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>