You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android中@JavascriptInterface调用retry()仅执行前两行的问题求助

Android 9下JavascriptInterface调用retry()时setText失效的排查与解决

核心原因

  • 线程执行环境问题:带@JavascriptInterface注解的方法是在WebView的后台线程(非主线程)执行的,而Android的UI操作必须在主线程完成。Android 9(API 28)对跨线程UI操作的限制更严格,setVisibility和setEnabled可能因View内部的轻量更新逻辑侥幸执行,但setText涉及文本绘制和View重绘的完整流程,非主线程调用会被系统静默丢弃,导致不生效。
  • WebView行为变更:相比旧版本,Android 9收紧了WebView与原生代码交互的线程模型,非主线程的UI操作不再有“容错”空间,直接被拦截。

解决方案(保留JavascriptInterface的前提下)

方案1:将retry()的UI操作全部切换到主线程

修改retry()方法,用runOnUiThread包裹所有UI相关代码,确保在主线程执行:

private void retry() {
    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            pr.setVisibility(View.GONE);
            lg.setEnabled(true);
            lg.setText("Retry");
        }
    });
}

如果项目支持Java 8及以上,可简化为Lambda写法:

private void retry() {
    runOnUiThread(() -> {
        pr.setVisibility(View.GONE);
        lg.setEnabled(true);
        lg.setText("Retry");
    });
}

方案2:在JavascriptInterface方法内切换到主线程调用retry()

如果不想修改retry()的原有逻辑,可在触发调用的processContent()方法内先切换线程:

@JavascriptInterface
public void processContent() {
    // 切到主线程再调用retry()
    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            retry();
        }
    });
}

验证步骤

可以先在processContent()中打印当前线程,确认问题根源:

@JavascriptInterface
public void processContent() {
    Log.d("WebViewThread", "Current thread: " + Thread.currentThread().getName());
    // 原有调用逻辑
}

如果日志输出的线程名称不是main,则完全印证了跨线程UI操作的问题。

内容的提问来源于stack exchange,提问作者Terre

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 09:03:47