https://rainmonth.github.io/posts/A180415.html
Android 原生与H5交互
[TOC]
JS中调用Android的函数方法
在Android程序中建立接口,并用建立的handler对象处理
1 | private Handler handler = new Handler(); |
通过给WebView添加JavaScriptInterface接口
即调用addJavaScriptInterface(new InJavaScript(), “injs”),其中第一个参数为前面定义的接口的实例,第二个参数为该对象对应的名字
在js代码中通过类似一下函数的方法调用Android中定义好的方法
1 | function sendToAndroid() { |
Android中调用JS中的方法
在JS代码中定义好要被Android程序调用的方法
1 | function getFromAndroid(str) { |
在Android程序中通过以下方式调用该方法(要注意调用的格式javascript:+要调用的方法名)
1 | Button button = (Button) findViewById(R.id.button); |
通过约定的scheme来完成H5到原生App的跳转
在H5要跳转到的原生页面所在的Activity中设定好scheme,如SplashActivity中
1
2
3
4
5
6
7<activity android:name=".SplashActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<data android:scheme="myapp" android:host="path" />
</intent-filter>
</activity>
其中schema表示这个链接的前缀,host代表短链的名字。如果你要在你的schema里面传参数,比如你要传uid和user_type,那么就跟普通的url的get参数格式一样:mls://userpage?uid=123&user_type=mogujie。
注意,中间千万不能有空格。
SplashActivity接受参数
1
2
3
4
5
6
7
8String uid,userType;
private void parseUriParams() {
Uri uri = getIntent().getData();
if (uri != null) {
uid = uri.getQueryParameter("uid");
userType = uri.getQueryParameter("user_type");
}
}在WebViewClient的shouldOverrideUrlLoading方法中作拦截URL判断
1
2
3
4
5
6
7
8
9
10
11
12
13public class MyWebChromeClient extends WebViewClient {
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (url.startsWith("mls://")) {
Intent intent = new Intent();
intent.setData(Uri.parse(url));
startActivity(intent);
Log.v("tag_2", url);
return true;
}
return super.shouldOverrideUrlLoading(view, url);
}
}
设置问题
通过WebView的setWebChromeClient方法还可以处理JS的警告、对话框以及输出JS控制台的信息到logcat中;
Android 4.2以后(API17+)出于安全因素的考虑,JS只能访问带有@JavascriptInterface注解的函数。
在此之前,任何public的函数都可以在JS中访问,而Java对象的继承关系会导致很多public函数都可以在JS中访问,其中一个重要的函数就是getClass()。然后JS可以通过反射来访问一些其他内容,就会出现安全问题,加上注解之后,JS就只能访问带有@JavascriptInterface注解的public函数,增强了安全性。