Convert Figma logo to code with AI

pedant logosafe-java-js-webview-bridge

为WebView中的Java与JavaScript提供【安全可靠】的多样互通方案

2,429
568
2,429
23

Top Related Projects

chrome browser of android version from chromium open project

Beautiful and customizable Android Activity that shows web pages within an app.

Enhanced WebView component for Android that works as intended out of the box

Proof of concept Android WebView implementation based on Chromium code

Quick Overview

Safe-java-js-webview-bridge is a library that provides a secure way to establish communication between JavaScript in a WebView and Java in an Android application. It aims to mitigate security risks associated with traditional WebView JavaScript interfaces by implementing a message-based communication system.

Pros

  • Enhances security by avoiding direct method exposure through addJavascriptInterface
  • Supports bidirectional communication between Java and JavaScript
  • Easy to integrate into existing Android projects
  • Allows for asynchronous communication, improving performance

Cons

  • May require refactoring of existing code that uses traditional WebView JavaScript interfaces
  • Limited documentation and examples available
  • Not actively maintained (last update was several years ago)
  • Potential performance overhead due to message-based communication

Code Examples

  1. Initializing the bridge in Java:
WebView webView = findViewById(R.id.webview);
SafeWebView safeWebView = new SafeWebView(webView);
safeWebView.addJavascriptInterface(new MyJavaScriptInterface(), "Android");
  1. Sending a message from JavaScript to Java:
window.Android.postMessage(JSON.stringify({
    action: 'getData',
    params: { id: 123 }
}));
  1. Handling messages in Java:
public class MyJavaScriptInterface extends JavascriptInterface {
    @Override
    public void onMessage(String message) {
        JSONObject json = new JSONObject(message);
        String action = json.getString("action");
        if ("getData".equals(action)) {
            // Handle getData action
        }
    }
}
  1. Sending a message from Java to JavaScript:
safeWebView.loadUrl("javascript:handleMessage(" + 
    JSONObject.quote(message) + ")");

Getting Started

  1. Add the library to your project (e.g., via Gradle):
implementation 'com.github.pedant:safe-java-js-webview-bridge:1.0.0'
  1. Initialize the SafeWebView in your activity:
WebView webView = findViewById(R.id.webview);
SafeWebView safeWebView = new SafeWebView(webView);
safeWebView.addJavascriptInterface(new MyJavaScriptInterface(), "Android");
  1. Implement the JavascriptInterface in your Java code:
public class MyJavaScriptInterface extends JavascriptInterface {
    @Override
    public void onMessage(String message) {
        // Handle incoming messages from JavaScript
    }
}
  1. Use the postMessage method in your JavaScript code to communicate with Java:
window.Android.postMessage(JSON.stringify({
    action: 'someAction',
    params: { key: 'value' }
}));

Competitor Comparisons

chrome browser of android version from chromium open project

Pros of AndroidChromium

  • Full-featured Chromium-based browser implementation for Android
  • Extensive documentation and community support
  • Regular updates and maintenance

Cons of AndroidChromium

  • Larger codebase and more complex implementation
  • Higher resource requirements for integration
  • Steeper learning curve for developers

Code Comparison

safe-java-js-webview-bridge:

@JavascriptInterface
public String getToken() {
    return Token.getToken();
}

AndroidChromium:

public class ChromiumActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initializeChromium();
    }
}

The safe-java-js-webview-bridge focuses on providing a secure interface between Java and JavaScript in WebViews, while AndroidChromium offers a complete Chromium-based browser implementation. The code snippets illustrate the difference in scope and complexity between the two projects.

safe-java-js-webview-bridge is more suitable for developers who need a lightweight solution for secure WebView communication. AndroidChromium is better suited for projects requiring a full-featured browser implementation with advanced capabilities.

Both projects have their merits, and the choice between them depends on the specific requirements of the application being developed. safe-java-js-webview-bridge offers simplicity and focused functionality, while AndroidChromium provides a comprehensive browser solution at the cost of increased complexity.

Beautiful and customizable Android Activity that shows web pages within an app.

Pros of FinestWebView-Android

  • Offers a more comprehensive and customizable WebView solution with additional features like progress bars, menus, and themes
  • Provides an easy-to-use builder pattern for quick implementation and configuration
  • Includes built-in support for various UI elements and animations

Cons of FinestWebView-Android

  • Larger library size and potentially higher resource usage due to additional features
  • May require more setup and configuration for simple use cases
  • Less focused on security aspects compared to safe-java-js-webview-bridge

Code Comparison

FinestWebView-Android:

new FinestWebView.Builder(activity)
    .showUrl(false)
    .titleDefault("My Web Page")
    .showSwipeRefreshLayout(true)
    .webViewBuiltInZoomControls(true)
    .show("https://example.com");

safe-java-js-webview-bridge:

WebView webView = (WebView) findViewById(R.id.webview);
JsBridge jsBridge = new JsBridge(webView);
jsBridge.register("jsMethod", new BridgeHandler() {
    @Override
    public void handler(String data, CallBackFunction function) {
        // Handle JavaScript call
    }
});

The code comparison shows that FinestWebView-Android focuses on easy customization and setup of the WebView, while safe-java-js-webview-bridge emphasizes secure communication between JavaScript and Java. FinestWebView-Android provides a more streamlined API for creating and configuring WebViews, whereas safe-java-js-webview-bridge offers a targeted solution for bridging JavaScript and Java interactions securely.

Enhanced WebView component for Android that works as intended out of the box

Pros of Android-AdvancedWebView

  • More comprehensive feature set, including file chooser, custom user agents, and multiple window support
  • Better handling of JavaScript interfaces and enhanced security measures
  • Active development with regular updates and bug fixes

Cons of Android-AdvancedWebView

  • Larger codebase, which may increase app size and complexity
  • Steeper learning curve due to additional features and customization options
  • May require more setup and configuration compared to the simpler safe-java-js-webview-bridge

Code Comparison

Android-AdvancedWebView:

AdvancedWebView mWebView = findViewById(R.id.webview);
mWebView.setListener(this, this);
mWebView.loadUrl("https://example.com");

safe-java-js-webview-bridge:

WebView webView = findViewById(R.id.webview);
JsBridge jsBridge = new JsBridge(webView);
jsBridge.register("nativeMethod", new JsBridge.Handler() { ... });

The Android-AdvancedWebView provides a more feature-rich implementation with built-in listener support, while safe-java-js-webview-bridge focuses on a simpler bridge between JavaScript and Java. Android-AdvancedWebView offers more out-of-the-box functionality, whereas safe-java-js-webview-bridge requires less setup for basic bridging needs.

Proof of concept Android WebView implementation based on Chromium code

Pros of chromeview

  • Uses the Chromium engine, providing better web standards compatibility and performance
  • Offers more advanced features like WebRTC and Web Audio API support
  • Provides a more consistent browsing experience across different Android versions

Cons of chromeview

  • Larger file size and increased app complexity due to bundling Chromium
  • Potentially higher memory usage compared to the native WebView
  • May require more frequent updates to keep up with Chromium releases

Code Comparison

safe-java-js-webview-bridge:

@JavascriptInterface
public String getData() {
    return "Safe data from Java";
}

chromeview:

mWebView.addJavascriptInterface(new Object() {
    @JavascriptInterface
    public String getData() {
        return "Data from Chromium-based WebView";
    }
}, "Android");

Both projects aim to provide a bridge between Java and JavaScript in Android WebViews, but they differ in their approach and underlying technology. safe-java-js-webview-bridge focuses on security and simplicity, while chromeview offers a more feature-rich and modern web rendering engine at the cost of increased complexity and resource usage.

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

Safe Java-JS WebView Bridge

抛弃使用高风险的WebView addJavascriptInterface方法,通过对js层调用函数及回调函数的包装,支持异步回调,方法参数支持js所有已知的类型,包括number、string、boolean、object、function。

安装

使用Safe Java-JS WebView Bridge最简单的办法就是像下面这样添加项目依赖。

Maven

<dependency>
  <groupId>com.google.code.gson</groupId>
  <artifactId>gson</artifactId>
  <version>2.3</version>
</dependency>
<dependency>
  <groupId>cn.pedant.safewebviewbridge</groupId>
  <artifactId>library</artifactId>
  <version>1.4</version>
  <type>aar</type>
</dependency>

Gradle

repositories {
    mavenCentral()
}

dependencies {
    compile 'cn.pedant.safewebviewbridge:library:1.4'
}

Sample

Sample 下载

image

用法

如何开始

初始化Webview WebSettings时允许js脚本执行,同时使用你的注入名和注入类来实例化一个InjectedChromeClient对象,然后关联到你的Webview实例。如demo中的例子(页面中引用的对象名为HostApp,指定的注入类为HostJsScope):

WebView wv = new WebView(this);
WebSettings ws = wv.getSettings();
ws.setJavaScriptEnabled(true);
wv.setWebChromeClient(
    new InjectedChromeClient("HostApp", HostJsScope.class)
);
wv.loadUrl("file:///android_asset/test.html");

自定义WebChromeClient子类

如果你需要实现自己的WebChromeClient子类,然后设置到WebView。为了保持InjectedChromeClient的功能,你需要将此类继承自InjectedChromeClient,同时像下面这样覆盖这三个方法。

public class CustomChromeClient extends InjectedChromeClient {

    public CustomChromeClient (String injectedName, Class injectedCls) {
        super(injectedName, injectedCls);
    }

    @Override
    public boolean onJsAlert(WebView view, String url, String message, final JsResult result) {
        // to do your work
        // ...
        return super.onJsAlert(view, url, message, result);
    }

    @Override
    public void onProgressChanged (WebView view, int newProgress) {
        super.onProgressChanged(view, newProgress);
        // to do your work
        // ...
    }

    @Override
    public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {
        // to do your work
        // ...
        return super.onJsPrompt(view, url, message, defaultValue, result);
    }
}

方法的定义

需要注入到网页的方法,必须在注入类中定义为public static且第一个参数接收WebView,其他参数的类型可以是int、long、double、boolean、String、JSONObject、JsCallback。方法执行时会默认将当前Webview的实例放到第一个参数,所以你的定义可能看起来像这样子的:

public static void testA (WebView webView) {}

网页调用如下:

HostApp.testA();

方法的重载

在定义时,支持不同参数类型或参数个数的方法重载,如:

public static int overloadMethod(WebView view, int val) {
    return val;
}
public static String overloadMethod(WebView view, String val) {
    return val;
}

但需要注意的是,由于JS中数字类型不区分整型、长整型、浮点类型等,是统一由64位浮点数表示,故Java方法在定义时int/long/double被当作是一种类型,也即:

public static int overloadMethod(WebView view, int val) {
    return val;
}
public static long overloadMethod(WebView view, long val) {
    return val;
}
public static double overloadMethod(WebView view, double val) {
    return val;
}

上面这三个方法并没有发生重载,HostApp.overloadMethod(1)调用时只会调用最后一个定义的方法(double类型定义的那个)。

方法的返回值

Java层方法可以返回void 或 能转为字符串的类型(如int、long、String、double、float等)或 可序列化的自定义类型。关于自定义类型的返回可以参见Demo下“从Java层返回Java对象”项对HostApp.retJavaObject()的调用。另外如果方法定义时返回void,那么网页端调用得到的返回值为null。

如果方法执行过程中出现异常,那么在网页JS端会抛出异常,可以catch后打印详细的错误说明。

关于异步回调

举例说明,首先你可以在Java层定义如下方法,该方法的作用是延迟设定的时间之后,用你传入的参数回调Js函数:

public static void delayJsCallBack(WebView view, int ms, final String backMsg, final JsCallback jsCallback) {
  TaskExecutor.scheduleTaskOnUiThread(ms*1000, new Runnable() {
      @Override
      public void run() {
          jsCallback.apply(backMsg);
      }
  });
}

那么在网页端的调用如下:

HostApp.delayJsCallBack(3, 'call back haha', function (msg) {
  HostApp.alert(msg);
});

即3秒之后会弹出你传入的'call back haha'信息。 故从上面的例子我们可以看出,你在网页端定义的回调函数是可以附加多个参数,Java方法在执行回调时需要带入相应的实参就行了。当然这里的回调函数的参数类型目前还不支持过复杂的类型,仅支持能够被转为字符串的类型。

另外需要注意的是一般传入到Java方法的js function是一次性使用的,即在Java层jsCallback.apply(...)之后不能再发起回调了。如果需要传入的function能够在当前页面生命周期内多次使用,请在第一次apply前**setPermanent(true)**。例如:

public static void setOnScrollBottomListener (WebView view, JsCallback jsCallback) {
	jsCallback.setPermanent(true);
	...
}

小心过大数字

JS中使用过大数字时,可能会导致精度丢失或者错误的数字结果,如下面:

HostApp.passLongType(14102300951321235)

传入一个大数14102300951321235到Java层,但Java层接收的数字实际上将会是14102300951321236这样一个错误的数字,所以当需要使用大数的情景下时,Java方法参数类型最好定义为String类型,而js层调用时也转为string,比如上面就为

HostApp.passLongType(14102300951321235+'')。	

更多实现细节见: http://www.pedant.cn/2014/07/04/webview-js-java-interface-research/

发布时防混淆

发布时需在你的混淆配置加入像下面这样的代码,注意返回到页面的自定义Java类以及注入类都要换成你项目中实际使用类名:

#--------------- BEGIN: Gson防混淆 ----------
-keepattributes *Annotation*
-keep class sun.misc.Unsafe { *; }
-keep class com.idea.fifaalarmclock.entity.***
-keep class com.google.gson.stream.** { *; }
#--------------- END ----------

#--------------- BEGIN: 返回到页面的自定义Java对象防混淆 ----------
-keepclassmembers class cn.pedant.SafeWebViewBridge.sample.HostJsScope$RetJavaObj{ *; }
#--------------- END ----------

#--------------- BEGIN: 注入到页面的接口类防混淆 ----------
-keepclassmembers class cn.pedant.SafeWebViewBridge.sample.HostJsScope{ *; }
#--------------- END ----------

License

The MIT License (MIT)

Copyright (c) 2014 Pedant(http://pedant.cn)

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.