Justson/AgentWeb · error · JsCallbackException
the JsCallback isn't permanent,cannot be called more than…
Error message
the JsCallback isn't permanent,cannot be called more than once
What it means
JsCallback.apply throws JsCallbackException when the callback is not permanent (mCouldGoOn == false) and apply() is called a second time. Non-permanent callbacks are single-use: the first apply() already ended the JS call chain (invoking the native completion on the JS side).
Solutions
- Call apply() at most once per JsCallback; pass all data in that single invocation
- For multiple invocations use the permanent-callback API (permanentCallback()/call()) so mCouldGoOn stays true
- Track a boolean 'called' flag around the callback usage
- Catch JsCallbackException on repeat calls and log instead of crashing
Example fix
// before
for (Item it : items) { callback.apply(it); } // second apply throws
// after
callback.permanentCallback();
for (Item it : items) { callback.call(it); } Defensive patterns
Strategy: try-catch
Validate before calling
if (!firstCall) { return; } // guard one-shot callback with a flag Try / catch
try { callback.apply(result); } catch (JsCallbackException e) { Log.w(TAG, "one-shot callback reused", e); } Prevention
- Call apply() exactly once per JsCallback
- Use permanentCallback() for repeated calls
- Deduplicate events before invoking callbacks
- Never retry apply() on failure with the same instance
When it happens
Trigger: Calling apply() twice on the same JsCallback returned for a one-shot JS native method (any callback not marked permanent), or retrying apply() after a failed first invocation.
Common situations: Looping over results and calling apply per item with a one-shot callback (should use permanentCallback + call() semantics instead), retry logic that re-invokes apply on exception, or duplicated event delivery calling the same callback twice.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- injected name can not be null
- the WebView related to the JsCallback has been recycled
- activity can not be null .
- ViewGroup is null,Please check your parameters .
- please check webcreator's create method was be called ?
AI-assisted analysis of Justson/AgentWeb@8f7f6adbf0 (2026-09-11).
Data as JSON: /api/errors/863f8e0c8073777f.
Report an issue: GitHub.
Appendix: source
Thrown at agentweb-core/src/main/java/com/just/agentweb/JsCallback.java:54
public JsCallback(WebView view, String injectedName, int index) {
mCouldGoOn = true;
mWebViewRef = new WeakReference<WebView>(view);
mInjectedName = injectedName;
mIndex = index;
}
/**
* 向网页执行js回调;
* @param args
* @throws JsCallbackException
*/
public void apply (Object... args) throws JsCallbackException {
if (mWebViewRef.get() == null) {
throw new JsCallbackException("the WebView related to the JsCallback has been recycled");
}
if (!mCouldGoOn) {
throw new JsCallbackException("the JsCallback isn't permanent,cannot be called more than once");
}
StringBuilder sb = new StringBuilder();
for (Object arg : args){
sb.append(",");
boolean isStrArg = arg instanceof String;
// 有的接口将Json对象转换成了String返回,这里不能加双引号,否则网页会认为是String而不是JavaScript对象;
boolean isObjArg = isJavaScriptObject(arg);
if (isStrArg && !isObjArg) {
sb.append("\"");
}
sb.append(String.valueOf(arg));
if (isStrArg && !isObjArg) {
sb.append("\"");
}
}
String execJs = String.format(CALLBACK_JS_FORMAT, mInjectedName, mIndex, mIsPermanent, sb.toString());
if (LogUtils.isDebug()) {
Log.d("JsCallBack", execJs);View on GitHub (pinned to 8f7f6adbf0)