从 JavaScript 调用 Android 方法
Posted
技术标签:
【中文标题】从 JavaScript 调用 Android 方法【英文标题】:Call Android methods from JavaScript 【发布时间】:2014-05-18 16:13:42 【问题描述】:我搜索了,但没有找到答案。我正在使用 html5 和 javascript 开发基于 webview 的 android 应用程序。我可以,例如 makeToast()
?
【问题讨论】:
查看这个答案***.com/questions/10472839/… 【参考方案1】:您可以通过将 JavaScript 接口添加到您的 WebView 并将特定方法公开给在您的 Web 视图中运行的 JavaScript 代码来实现此目的。换句话说,您需要将对 Android 的 Toast 类的调用封装在您在 Activity/Fragment 中创建的方法中。
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_
android:layout_>
<WebView android:id="@+id/web_view"
android:layout_
android:layout_/>
</RelativeLayout>
MainActivity.java
public class MainActivity extends Activity
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
WebView webView = (WebView)findViewById(R.id.web_view);
webView.loadUrl("file:///android_asset/web.html");
webView.getSettings().setJavaScriptEnabled(true);
webView.addJavascriptInterface(new WebViewJavaScriptInterface(this), "app");
/*
* JavaScript Interface. Web code can access methods in here
* (as long as they have the @JavascriptInterface annotation)
*/
public class WebViewJavaScriptInterface
private Context context;
/*
* Need a reference to the context in order to sent a post message
*/
public WebViewJavaScriptInterface(Context context)
this.context = context;
/*
* This method can be called from Android. @JavascriptInterface
* required after SDK version 17.
*/
@JavascriptInterface
public void makeToast(String message, boolean lengthLong)
Toast.makeText(context, message, (lengthLong ? Toast.LENGTH_LONG : Toast.LENGTH_SHORT)).show();
资产/web.html
<!DOCTYPE html>
<html>
<head>
<title>JavaScript View</title>
<script type="text/javascript">
function showToast()
var message = document.getElementById("message").value;
var lengthLong = document.getElementById("length").checked;
/*
Call the 'makeToast' method in the Java code.
'app' is specified in MainActivity.java when
adding the JavaScript interface.
*/
app.makeToast(message, lengthLong);
return false;
/*
Call the 'showToast' method when the form gets
submitted (by pressing button or return key on keyboard).
*/
window.onload = function()
var form = document.getElementById("form");
form.onsubmit = showToast;
</script>
</head>
<body>
<form id="form">
Message: <input id="message" name="message" type="text"/><br />
Long: <input id="length" name="length" type="checkbox" /><br />
<input type="submit" value="Make Toast" />
</form>
</body>
</html>
【讨论】:
太棒了,这正是我所需要的。谢谢! @Ian,这看起来正是我正在寻找的,但是当我从我的 JavaScript 中调用该方法时出现错误,如下所示:(function(event)appInterface.reloadSite();return false;)
。这是在 HTML IMG 元素上使用 onClick="appInterface.reloadSite();return false;"
调用的,我的 JavaScript 界面是使用 mWebView.addJavascriptInterface(new WebViewJavaScriptInterface(this), "appInterface");
创建的,不幸的是 Chrome 的调试检查器控制台中的错误不是很有帮助。
抱歉,我不确定。也许 Java 代码缺少 @JavascriptInterface 注释??
我有两个方法要从 JavaScript onClick 事件中调用,并且在 WebViewJavaScriptInterface 类中的定义之前都有 @JavascriptInterace。如何从 JavaScript 调用方法(通过回调或其他方式)是否有什么特别需要的,或者我可以直接通过我描述的 onClick 事件调用?
我发现了我的问题...我调用的方法做了需要在 UI 线程中运行的事情。似乎任何通过 JavaScript 接口运行的东西都会在它自己的线程中运行,所以你需要使用RunOnUiThread()
- 如***.com/questions/5161951/… 中所述 - 做任何影响视图等的事情。【参考方案2】:
查看WebView
的addJavascriptInterface()
方法:
http://developer.android.com/reference/android/webkit/WebView.html#addJavascriptInterface%28java.lang.Object,%20java.lang.String%29
【讨论】:
【参考方案3】:只是因为它更方便(布局):
<?xml version="1.0" encoding="utf-8"?>
<WebView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/webView"
android:layout_
android:layout_ />
【讨论】:
你在说什么? 我说如果WebView在屏幕上拉伸的话,在RelativeLayout中插入WebView是没有意义的。 WebView 逻辑上用作根元素。【参考方案4】:创建 Main Activity 代码后,您需要创建 Javascript 代码并从中调用 WebviewInterface,让我们看看示例:
public class MainActivity extends AppCompatActivity
String TAG = "MainActivity";
Context context;
WebView mWebView;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
context = this;
mWebView = (WebView) findViewById(R.id.webview);
initWebView();
String ENROLLMENT_URL = "file:///android_asset/about_page.html";
mWebView.loadUrl(ENROLLMENT_URL);
@SuppressLint( "SetJavaScriptEnabled" )
private void initWebView()
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.setWebChromeClient(new WebChromeClient());
mWebView.addJavascriptInterface(new WebviewInterface(), "Interface");
public class WebviewInterface
@JavascriptInterface
public void javaMehod(String val)
Log.i(TAG, val);
Toast.makeText(context, val, Toast.LENGTH_SHORT).show();
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_
android:layout_
tools:context="com.legendblogs.android.MainActivity">
<WebView
android:layout_
android:layout_
android:id="@+id/webview"/>
</RelativeLayout>
Look at this link to see full example https://www.legendblogs.com/blog/how-to-call-native-java-methods-from-webview-javascript/121764
【讨论】:
以上是关于从 JavaScript 调用 Android 方法的主要内容,如果未能解决你的问题,请参考以下文章
在android中安排后台任务并从任务中调用react-native javascript方法
Android 在 WebView 中调用 JavaScript 函数
javax.net.ssl.SSLException:SSL 握手中止连接由对等方重置,同时调用 web 服务 Android