webview系列:Html5页面和Native App怎么进行交互
混合开发的App(Hybrid App)就是在一个App中内嵌一个轻量级的浏览器,一部分原生的功能改为Html5来开发,这部分功能不仅能够在不升级App的情况下动态更新,而且可以在Android或iOS的App上同时运行,让用户的体验更好又可以节省开发的资源。
我觉得一个Hybrid开发的App中必须要要有的功能就是Html5页面和Native App怎么进行交互。比如,我点了一个Html 5页面上的一个按钮或链接,我能不能够跳转到Native App的某个页面;比如我点了Html 5页面上的分享按钮,我能不能调用Native App的分享功能;比如Html加载的时候能不能获取Native App的用户信息等等。
一般来讲,我所知道的两种主流的方式就是:
js调用Native中的代码
Schema:WebView拦截页面跳转
第2种方式实现起来很简单,但是一个致命的问题就是这种交互方式是单向的,Html5无法实现回调。如果需求变得复杂,假如Html5需要获取Native App中的用户信息,那么最好使用js调用的方式。例如我们通过淘宝客户端进入天猫的h5页面购物,在这种情况下,你就需要在webview页面获取登陆用户的信息。
一.方式1:js和Native进行交互
demo
webview相关页面配置
WebSettings webSettings = mWebview.getSettings();
//①设置WebView允许调用js
webSettings.setJavaScriptEnabled(true);
webSettings.setDefaultTextEncodingName("UTF-8");
//②将object对象暴露给Js,调用addjavascriptInterface
mWebview.addJavascriptInterface(new MyObject(TestWebViewActivity.this), "myObj");
- 1
- 2
- 3
- 4
- 5
- 6
- 7
静态页面
<html>
<head>
<title>Js调用Android</title>
</head>
<body>
<a href="xl://goods:8888/goodsDetail?goodsId=10011002">test scheme</a>
<input type="button" value="Toast提示" onclick="myObj.showToast('曹神前来日狗~');"/>
<input type="button" value="列表对话框" onclick="myObj.showDialog();"/>
</body>
</html>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
MyObject
/**
* Created by niehongtao on 16/10/9.
*/
public class MyObject {
private Context context;
public MyObject(Context context) {
this.context = context;
}
//将显示Toast和对话框的方法暴露给JS脚本调用
@JavascriptInterface
public void showToast(String name) {
Toast.makeText(context, name, Toast.LENGTH_SHORT).show();
}
@JavascriptInterface
public void showDialog() {
new AlertDialog.Builder(context)
.setTitle("联系人列表").setIcon(R.mipmap.ic_launcher)
.setItems(new String[]{"基神", "B神", "曹神", "街神", "翔神"}, null)
.setPositiveButton("确定", null).create().show();
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
可参考
Android基础入门教程——7.5.2 WebView和JavaScrip交互基础
http://blog.csdn.net/coder_pig/article/details/48392621
这个讲解的最为具体
二.方式2:Scheme:WebView拦截页面跳转
demo
点击网页里的超链接,跳转到原生页面
webviewActivity
package com.ht.fyforandroid.test.webview;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.KeyEvent;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import com.ht.fyforandroid.R;
import com.ht.fyforandroid.base.BaseActivity;
import butterknife.InjectView;
/**
* Created by niehongtao on 16/7/7.
* 进行仿微信加载WebView显示进度条,直接调用start()方法进行跳转.
*/
public class TestWebViewActivity extends BaseActivity {
@InjectView(R.id.webview)
WebView mWebview;
@Override
protected int getLayoutId() {
return R.layout.activity_webview;
}
@Override
protected void init(Bundle savedInstanceState) {
TestWebViewActivity.super.mLoadingDialog.hideLoading();
mWebview.loadUrl("file:///android_asset/test.html");
mWebview.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
Uri uri = Uri.parse(url);
if (uri.getScheme().equals("xl")) {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
} else {
view.loadUrl(url);
}
return true;
}
});
}
public static void startActivity(Context context) {
Intent intent = new Intent(context, TestWebViewActivity.class);
context.startActivity(intent);
}
@Override
protected void onDestroy() {
super.onDestroy();
if (mWebview != null) {
mWebview.destroy();
}
}
}
- 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
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
静态页面test.html
<html>
<body>
<a href="xl://goods:8888/goodsDetail?goodsId=10011002">test scheme</a>
</body>
</html>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
需要跳转到的页面
配置信息
<activity android:name=".test.scheme.Test1Activity">
<!--要想在别的App上能成功调起App,必须添加intent过滤器-->
<intent-filter>
<!--协议部分,随便设置-->
<data
android:host="goods"
android:path="/goodsDetail"
android:port="8888"
android:scheme="xl"
/>
<!--下面这几行也必须得设置-->
<category android:name="android.intent.category.DEFAULT"/>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.BROWSABLE"/>
</intent-filter>
</activity>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
页面
package com.ht.fyforandroid.test.scheme;
import android.os.Bundle;
import com.ht.fyforandroid.R;
import com.ht.fyforandroid.base.BaseActivity;
/**
* Created by niehongtao on 16/10/8.
*/
public class Test1Activity extends BaseActivity {
@Override
protected int getLayoutId() {
return R.layout.activity_test1;
}
@Override
protected void init(Bundle savedInstanceState) {
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
<?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"
>
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="scheme跳转测试"
/>
</LinearLayout>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
应用场景:
Android中的scheme是一种非常好的实现机制,通过定义自己的scheme协议,可以非常方便跳转app中的各个页面;
通过scheme协议,服务器可以定制化告诉App跳转那个页面,可以通过通知栏消息定制化跳转页面,可以通过H5页面跳转页面等。
已经可以适应多数的应用场景