Android 原生页面同H5交互
JS中调用Android的函数方法
在Android程序中建立接口,并用建立的handler对象处理
private Handler handler = new Handler(); final class InJavaScript{ public void runOnAndroidJavaScript(final String str){ handler.post(new Runnable() { public void run() { // todo 对传递过来的参数进行处理 } }) } }
通过给WebView添加JavaScriptInterface接口
即调用addJavaScriptInterface(new InJavaScript(), “injs”),其中第一个参数为前面定义的接口的实例,第二个参数为该对象对应的名字
在js代码中通过类似一下函数的方法调用Android中定义好的方法
function sendToAndroid() { var str = "Call the Android method in js"; window.injs.runOnAndroidJavaScript(str);// injs为Android程序中建立的InJavaScript对象的一个实例名字 }
Android中调用JS中的方法
在JS代码中定义好要被Android程序调用的方法
function getFromAndroid(str) { document.getElementById("android").innerHTML = str; }
在Android程序中通过以下方式调用该方法(要注意调用的格式javascript:+要调用的方法名)
Button button = (Button) findViewById(R.id.button); button.setOnClickListener(new OnClickListener() { public void onClick(View arg0) { //调用javascript中的方法 webView.loadUrl("javascript:getFromAndroid('Cookie call the js function from Android')"); } });
通过约定的scheme来完成H5到原生App的跳转
在H5要跳转到的原生页面所在的Activity中设定好scheme,如SplashActivity中
<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接受参数
String uid,userType; private void parseUriParams() { Uri uri = getIntent().getData(); if (uri != null) { uid = uri.getQueryParameter("uid"); userType = uri.getQueryParameter("user_type"); } }
在WebViewClient的shouldOverrideUrlLoading方法中作拦截URL判断
public class MyWebChromeClient extends WebViewClient { @Override 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函数,增强了安全性。
发现了一篇 WebView与JS交互的好文,请猛戳 最全面总结 Android WebView与 JS 的交互方式 !