WebView: java.lang.Throwable: A
2022-02-16 本文已影响0人
xq9527
前言:
各位同学大家好,有段时间没有给各位更新文章了 ,最近公司在用laya来发一个app 底层还是js实现 在安卓跟js交互时候出现了如标题的问题 所以就记录一下
具体问题
@JavascriptInterface
public void getDeviceInfo(){
DeviceInfo deviceInfo=new DeviceInfo();
deviceInfo.setDevice_model(DeviceUtil.getModel());
deviceInfo.setVersion(VersionUtil.versionName(mContext));
deviceInfo.setDevice_id(DeviceUtil.getAndroidId(mContext));
deviceInfo.setDevice_os(DeviceUtil.getSystemVersion());
Gson gson=new Gson();
String deviceinfo=gson.toJson(deviceInfo);
Log.e(TAG, "getDeviceInfo: "+deviceinfo );
mWebView.loadUrl("javascript:if(window.nativeSendDeviceInfo){window.nativeSendDeviceInfo('"+deviceinfo+"')}");
// mWebView.loadUrl("javascript:window.nativeSendDeviceInfo('"+deviceinfo+"')");
}
首先我们看这段代码 我们乍一看 没毛病是不是 我们让js先调用native 方法然后我拿到设备信息 组装数据 转成json字符串 然后native 再去调用js 看着是没问题 如果我们之间调 就会出现
如上的错误
WebView: java.lang.Throwable: A WebView method was called on thread 'JavaBridge'. All WebView methods must be called on the same thread
提示我们要在主线程来对webview进行更新操作
我们可以通过调用 runOnUiThread 重写 实现 Runnable 接口重写run方法切换到UI 线程 然后在对 webview进行更新操作
runOnUiThread(new Runnable() {
@Override
public void run() {
mWebView.loadUrl("javascript:if(window.nativeSendDeviceInfo){window.nativeSendDeviceInfo('"+deviceinfo+"')}");
}
});
或者你handler 发消息切换到UI线程也是可以的
@JavascriptInterface
public void getDeviceInfo(){
DeviceInfo deviceInfo=new DeviceInfo();
deviceInfo.setDevice_model(DeviceUtil.getModel());
deviceInfo.setVersion(VersionUtil.versionName(mContext));
deviceInfo.setDevice_id(DeviceUtil.getAndroidId(mContext));
deviceInfo.setDevice_os(DeviceUtil.getSystemVersion());
Gson gson=new Gson();
String deviceinfo=gson.toJson(deviceInfo);
Log.e(TAG, "getDeviceInfo: "+deviceinfo );
// mWebView.loadUrl("javascript:if(window.nativeSendDeviceInfo){window.nativeSendDeviceInfo('"+deviceinfo+"')}");
Message msg = new Message();
msg.what = 1;
Bundle data = new Bundle();
//将获取到的String装载到msg中
data.putString("value", deviceinfo);
msg.setData(data);
// msg.obj=deviceInfo;
handler.sendMessage(msg);
}
private Handler handler=new Handler(){
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
switch (msg.what){
case 1:
Bundle data = msg.getData();
String getdeviceinfo = data.getString("value");
Log.e(TAG, "handleMessage: 切换线程成功 " );
// String getdeviceinfo= (String) msg.obj;
Log.e(TAG, "handleMessage: getdeviceinfo"+getdeviceinfo );
mWebView.loadUrl("javascript:if(window.nativeSendDeviceInfo){window.nativeSendDeviceInfo('"+getdeviceinfo+"')}");
break;
default:
break;
}
}
};
最后总结:
在与JS交互的方法中不能直接操作View,需要放在主线程操作才能生效 所以我们在操作更新webview直接我们要切换到UI线程去操作 我这边遇到这个问题 所以记录下 有些同学在处理的时候可能也没注意很难发现 因为程序没有崩溃 但是js那边取不到值 所以要注意 最后希望我的文章和笔记能帮助到各位同学学习和工作。