Last active
August 1, 2024 08:10
-
-
Save EaseTheWorld/12f73e1d1466d8d570f36b3e49e79a39 to your computer and use it in GitHub Desktop.
Simple implementation of AndroidPromise(Run android async work from javascript using ES6 Promise/async/await)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var AndroidPromise = { | |
callbacks: {}, | |
requestId: 0, | |
request: function (work, params={}) { | |
return new Promise((resolve, reject) => { | |
let requestId = this.requestId++ | |
this.callbacks[requestId] = { | |
'resolve': resolve, | |
'reject': reject | |
} | |
AndroidAsyncRequest.request(work, JSON.stringify(params), | |
'AndroidPromise.onResolve('+requestId+')', | |
'AndroidPromise.onReject('+requestId+')' | |
) | |
}) | |
}, | |
onResolve: function (requestId) { | |
let callback = this.callbacks[requestId].resolve | |
delete this.callbacks[requestId] | |
return callback | |
}, | |
onReject: function (requestId) { | |
let callback = this.callbacks[requestId].reject | |
delete this.callbacks[requestId] | |
return callback | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
fun interface AsyncRequest { | |
fun request(workId: String, params: String, successCallback: Callback, failCallback: Callback) | |
fun interface Callback { | |
fun onResult(result: String) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class AsyncRequestJavascriptInterface(private val delegate: Delegate) { | |
@JavascriptInterface | |
fun request(workId: String, params: String, successJsCallback: String, failJsCallback: String) { | |
return delegate.request(workId, params, successJsCallback, failJsCallback) | |
} | |
companion object { | |
const val JAVASCRIPT_INTERFACE_NAME = "AndroidAsyncRequest" | |
} | |
fun interface Delegate { | |
fun request(workId: String, params: String, successJsCallback: String, failJsCallback: String) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@SuppressLint("SetJavaScriptEnabled") | |
class AsyncWebView @JvmOverloads constructor( | |
context: Context, | |
attrs: AttributeSet? = null, | |
): WebView(context, attrs) { | |
init { | |
settings.javaScriptEnabled = true | |
} | |
fun setWorkRequestProvider(asyncRequest: AsyncRequest) { | |
addJavascriptInterface(createAsyncRequestJavascriptInterface(asyncRequest), | |
AsyncRequestJavascriptInterface.JAVASCRIPT_INTERFACE_NAME) | |
} | |
private fun createAsyncRequestJavascriptInterface(asyncRequest: AsyncRequest) = | |
AsyncRequestJavascriptInterface { workId, params, successJsCallback, failJsCallback -> | |
val successCallback = AsyncRequest.Callback { | |
evaluateJavascript("$successJsCallback('$it')", null) | |
} | |
val failCallback = AsyncRequest.Callback { | |
evaluateJavascript("$failJsCallback('$it')", null) | |
} | |
post { | |
asyncRequest.request(workId, params, successCallback, failCallback) | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<script src="file:///android_asset/AndroidPromise.js"></script> | |
</head> | |
<body> | |
<script> | |
function printStatus(s) { | |
let d = new Date() | |
let line = "<br>" + d.getHours()+":"+d.getMinutes()+":"+d.getSeconds() + " " + s | |
document.getElementById('status').innerHTML += line | |
} | |
async function test1(work, params) { | |
printStatus(work + " start ("+params+")") | |
let response = await AndroidPromise.request(work, params) | |
printStatus(work + " end ("+response+")") | |
} | |
</script> | |
<div onclick="test1('work1', 3000).then(function(){console.log('after test1')})"> | |
<p>work1</p> | |
</div> | |
<div onclick="test1('work2', 5000)"> | |
<p>work2</p> | |
</div> | |
<div id="status"> | |
<hr> | |
</div> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hello :-)
I also had some trouble to implement a javascript interface with the android SDK. Based on the idea in the gist you referenced in your comment I created a SimpleAndroidBridge which allows you to build an easy interface between android(kotlin) and webview(java) with a full promise support.
Just check it out and let me now what you think about it :-)