Skip to content

Commit 26220df

Browse files
author
lemon
committed
支持在Java中调用JavaScript,并获取返回值
1 parent 7dc834f commit 26220df

File tree

10 files changed

+139
-59
lines changed

10 files changed

+139
-59
lines changed
-587 Bytes
Binary file not shown.

.idea/inspectionProfiles/Project_Default.xml

Lines changed: 17 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/src/main/assets/demo.html

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,20 @@
66
<meta http-equiv="X-UA-Compatible" content="IE=edge">
77
<title>Page Title</title>
88
<meta name="viewport" content="width=device-width, initial-scale=1">
9-
<script src="easybridge.js"></script>
109
<script type="text/javascript">
1110

1211
document.addEventListener('WebViewJavascriptBridgeReady',
1312
function () {
1413
toast('inject finished');
14+
window['easyBridge'].resultBack = function (parameters, callback) {
15+
if (typeof callback == 'function') {
16+
callback(parameters);
17+
}
18+
};
1519
}, false);
1620

1721
function toast(params = 'toast data') {
18-
window['easyBridge'].callHandler('toast', 'toast with:'+params+'at '+new Date().toLocaleString());
22+
window['easyBridge'].callHandler('toast', 'toast with:' + params + 'at ' + new Date().toLocaleString());
1923
}
2024
</script>
2125
</head>

app/src/main/java/easily/tech/easybridge/MainActivity.kt

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@ import android.support.v7.app.AppCompatActivity
55
import android.os.Bundle
66
import android.webkit.WebChromeClient
77
import android.webkit.WebView
8+
import android.widget.Toast
89
import easily.tech.easybridge.handler.ToastHandler
910
import easily.tech.easybridge.lib.EasyBridgeWebChromeClient
11+
import easily.tech.easybridge.lib.ResultCallBack
1012
import easily.tech.easybridge.lib.SecurityPolicyChecker
1113
import kotlinx.android.synthetic.main.activity_main.*
1214

@@ -18,17 +20,16 @@ class MainActivity : AppCompatActivity() {
1820
WebView.setWebContentsDebuggingEnabled(true)
1921
}
2022
setContentView(R.layout.activity_main)
21-
webView.webChromeClient = object : EasyBridgeWebChromeClient(webView) {
22-
override fun onProgressChanged(view: WebView?, newProgress: Int) {
23-
super.onProgressChanged(view, newProgress)
24-
val script = String.format("%s.callHandler('toast','current progress:%s')", webView.bridgeName, newProgress)
25-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
26-
webView.evaluateJavascript(script) {
27-
}
28-
}
29-
}
30-
}
3123
webView.registerHandler(ToastHandler(this))
3224
webView.loadUrl("file:///android_asset/demo.html")
25+
// call JavaScript From Java
26+
webView.postDelayed({
27+
webView.callHandler("resultBack", "this is the value pass from Java", object : ResultCallBack() {
28+
override fun onResult(result: Any?) {
29+
Toast.makeText(this@MainActivity, result?.toString(), Toast.LENGTH_SHORT).show()
30+
}
31+
32+
})
33+
}, 5000)
3334
}
3435
}

easybridge/src/main/assets/easybridge.js

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,16 +31,48 @@
3131
parameters = args || {};
3232
parameters = JSON.stringify(parameters);
3333
}
34-
//the name '_easybridge' is an java object that mapping to a javascrip onject,using addJavaInterface in Java code
34+
//the name '_easybridge' is an java object that mapping to a javascript onject,using addJavaInterface in Java code
3535
if (window._easybridge) {
3636
setTimeout(function () {
37+
//the function enqueue is the pubic method from Java Code,using to call Java logic
3738
_easybridge.enqueue(handlerName, location.href, parameters, callbackId);
3839
}, 0);
3940
} else {
4041
console.error(bridgeName + ':' + "the mapping object '_easybridge' had not been added any more");
4142
}
4243
}
4344

45+
//the function for Java Code to invoked JavaScript function
46+
function _executeScript(handlerName, parameters, callbackId) {
47+
if (!handlerName) {
48+
console.error('invalid handlerName from Java code');
49+
return;
50+
}
51+
var handler = window[bridgeName][handlerName];
52+
if (!handler) {
53+
console.error('the handler with name \'' + handlerName + '\' to be invoked is not existed');
54+
return;
55+
}
56+
try {
57+
if (callbackId) {
58+
callbackFunc = function (result) {
59+
if (window._easybridge) {
60+
//the method onExecuteJSCallback is a Java Code,using to dispatch result after execute the JavaScript function from Java
61+
_easybridge.onExecuteJSCallback(callbackId, result);
62+
} else {
63+
console.error(bridgeName + ':' + "the mapping object '_easybridge' had not been added any more");
64+
}
65+
};
66+
handler(parameters, callbackFunc);
67+
} else {
68+
handler(parameters);
69+
}
70+
} catch (exception) {
71+
console.error(exception);
72+
}
73+
}
74+
75+
4476
//the function for the java code to dispatch the result
4577
function _dispatchResult(callbackId, result) {
4678
//find the target callback function and invoke it
@@ -72,7 +104,9 @@
72104
//init the bridge object
73105
window[bridgeName] = {
74106
callHandler: callHandler,
107+
_executeScript: _executeScript,
75108
_dispatchResult: _dispatchResult,
109+
76110
};
77111
//notify to javascript that the bridge had been init
78112
var doc = document;

easybridge/src/main/java/easily/tech/easybridge/lib/EasyBridge.java

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import android.os.Build;
44
import android.os.Handler;
5-
import android.os.Message;
65
import android.text.TextUtils;
76
import android.webkit.JavascriptInterface;
87
import android.webkit.ValueCallback;
@@ -32,15 +31,19 @@ private static class CallBackHandler extends Handler {
3231

3332
private static final String JAVA_SCRIPT_PROTOCOL = "javascript:";
3433
private static final String CALLBACK_FUNCTION = "%s._dispatchResult(\"%s\",\'%s\')";
34+
private static final String EXECUTE_SCRIPT = "%s._executeScript(\'%s\',\'%s\',\'%s\')";
3535

3636
private Map<String, BridgeHandler> registerHandlerMap;
37+
private Map<String, ResultCallBack> jsCallbackMap;
3738
private CallBackHandler callBackHandler;
3839
private SoftReference<WebView> bridgeWebView;
3940
private String bridgeName;
41+
private static long uniqueId = 1;
4042

4143
EasyBridge(WebView webView, String bridgeName) {
4244
this.bridgeName = bridgeName;
4345
registerHandlerMap = new HashMap<>();
46+
jsCallbackMap = new HashMap<>();
4447
this.bridgeWebView = new SoftReference<>(webView);
4548
this.callBackHandler = new CallBackHandler();
4649
}
@@ -84,6 +87,39 @@ public void run() {
8487
});
8588
}
8689

90+
/**
91+
* a method using to return the result from the Java Code execute the JavaScript
92+
*
93+
* @param callbackId the uniqueId for request
94+
* @param result the result from JavaScript
95+
*/
96+
@JavascriptInterface
97+
public void onExecuteJSCallback(String callbackId, final String result) {
98+
if (jsCallbackMap == null || jsCallbackMap.isEmpty() || TextUtils.isEmpty(callbackId)) {
99+
return;
100+
}
101+
final ResultCallBack resultCallBack = jsCallbackMap.get(callbackId);
102+
if (resultCallBack != null) {
103+
jsCallbackMap.remove(callbackId);
104+
callBackHandler.post(new Runnable() {
105+
@Override
106+
public void run() {
107+
resultCallBack.onResult(result);
108+
}
109+
});
110+
}
111+
}
112+
113+
void callHandler(String handlerName, String parameters, ResultCallBack resultCallBack) {
114+
String callbackId = "";
115+
if (resultCallBack != null) {
116+
callbackId = "cb_" + (uniqueId++) + System.currentTimeMillis();
117+
jsCallbackMap.put(callbackId, resultCallBack);
118+
}
119+
String executeScript = String.format(EXECUTE_SCRIPT, bridgeName, handlerName, parameters, callbackId);
120+
executeScriptInMain(executeScript);
121+
}
122+
87123

88124
/**
89125
* if js invoke the java async ,that the result will be returned by execute a script in the bridge
@@ -157,4 +193,13 @@ void clear() {
157193
}
158194
}
159195

196+
void destroy() {
197+
if (registerHandlerMap != null) {
198+
registerHandlerMap.clear();
199+
}
200+
if (jsCallbackMap != null) {
201+
jsCallbackMap.clear();
202+
}
203+
}
204+
160205
}

easybridge/src/main/java/easily/tech/easybridge/lib/EasyBridgeWebView.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,13 @@ public void unregisterHandler(String handlerName) {
6262
}
6363
}
6464

65+
// use to execute JavaScript
66+
public void callHandler(String handlerName, String parameters, ResultCallBack resultCallBack) {
67+
if (easyBridge != null) {
68+
easyBridge.callHandler(handlerName, parameters, resultCallBack);
69+
}
70+
}
71+
6572
public void clear() {
6673
if (easyBridge != null) {
6774
easyBridge.clear();
@@ -79,4 +86,12 @@ public SecurityPolicyChecker getPolicyChecker() {
7986
public void setPolicyChecker(SecurityPolicyChecker policyChecker) {
8087
this.policyChecker = policyChecker;
8188
}
89+
90+
@Override
91+
protected void onDetachedFromWindow() {
92+
super.onDetachedFromWindow();
93+
if (easyBridge != null) {
94+
easyBridge.destroy();
95+
}
96+
}
8297
}

easybridge/src/main/java/easily/tech/easybridge/lib/EasyBridgeWebViewClient.java

Lines changed: 0 additions & 40 deletions
This file was deleted.

easybridge/src/main/java/easily/tech/easybridge/lib/ResultCallBack.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,14 @@ public abstract class ResultCallBack {
99
*/
1010
private String callbackId;
1111

12-
public ResultCallBack(String callbackId) {
12+
public ResultCallBack() {
13+
}
14+
15+
ResultCallBack(String callbackId) {
1316
this.callbackId = callbackId;
1417
}
1518

16-
public String getCallbackId() {
19+
String getCallbackId() {
1720
return callbackId;
1821
}
1922

easybridge/src/main/java/easily/tech/easybridge/lib/Utils.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,12 @@ public static synchronized String readAssetFile(Context context, String path) {
1717
try {
1818
inputStream = context.getAssets().open(path);
1919
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
20-
String line = null;
20+
String line;
2121
StringBuilder fileContent = new StringBuilder();
2222
do {
2323
line = bufferedReader.readLine();
2424
// ignore the comments string in file
25-
if (line != null && !line.matches("^\\s*\\/\\/.*")) {
25+
if (line != null && !line.matches("^\\s*//.*")) {
2626
fileContent.append(line);
2727
}
2828
} while (line != null);
@@ -35,7 +35,8 @@ public static synchronized String readAssetFile(Context context, String path) {
3535
if (inputStream != null) {
3636
try {
3737
inputStream.close();
38-
} catch (IOException e) {
38+
} catch (IOException exception) {
39+
exception.printStackTrace();
3940
}
4041
}
4142
}

0 commit comments

Comments
 (0)