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
相关产品推荐
相关产品推荐

