Closed senda58 closed 1 year ago
大概分析了一下原因,在cordova 框架中 public class SystemWebView extends WebView ,而插件在编译时,将WebView 替换了ShadowWebview 导致初始化时,转化类型出错。这个怎么改呢?
@shifujun 能给讲讲,宿主加载weview 资源文件的原理么? 插件编译时将WebView 替换了ShadowWebview 意义在于什么呢?
webview的处理原因可以blame一下shadowwebview那个文件看到提交记录。
这里的bug应该是 ebb33a85 处理时没考虑到子类可能需要对应的client子类。
解决这个bug需要再review一下init时需要初始化client的原因。以及如何确定client子类,如何构造client子类对象。
这个是cordova框架自带的。还是没明白该咋改, 我想知道插件编译时将WebView 替换了ShadowWebview 意义在于什么呢? @shifujun
你翻阅ShadowWebview的提交记录和实现就会发现它和从assets中加载url的关系了。
@shifujun 为什么不能 使用ShdowWebView子类自己的setWebviewClient 呢? 也就是说 使用插件自己webview的逻辑呢?
下面是cordova框架 自带的webview子类,麻烦大佬给分析一下,谢谢了
public class SystemWebView extends WebView implements CordovaWebViewEngine.EngineView {
private SystemWebViewClient viewClient;
SystemWebChromeClient chromeClient;
private SystemWebViewEngine parentEngine;
private CordovaInterface cordova;
public SystemWebView(Context context) {
this(context, null);
}
public SystemWebView(Context context, AttributeSet attrs) {
super(context, attrs);
}
// Package visibility to enforce that only SystemWebViewEngine should call this method.
void init(SystemWebViewEngine parentEngine, CordovaInterface cordova) {
this.cordova = cordova;
this.parentEngine = parentEngine;
if (this.viewClient == null) {
setWebViewClient(new SystemWebViewClient(parentEngine));
}
if (this.chromeClient == null) {
setWebChromeClient(new SystemWebChromeClient(parentEngine));
}
}
@Override
public CordovaWebView getCordovaWebView() {
return parentEngine != null ? parentEngine.getCordovaWebView() : null;
}
@Override
public void setWebViewClient(WebViewClient client) {
viewClient = (SystemWebViewClient)client;
super.setWebViewClient(client);
}
@Override
public void setWebChromeClient(WebChromeClient client) {
chromeClient = (SystemWebChromeClient)client;
super.setWebChromeClient(client);
}
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
Boolean ret = parentEngine.client.onDispatchKeyEvent(event);
if (ret != null) {
return ret.booleanValue();
}
return super.dispatchKeyEvent(event);
}
}
肯定是可以的,也应该使用原本业务定义的子类的。你理解错了。我们就是把WebView换成了ShadowWebView,加了一层逻辑而已。
@shifujun 好,谢谢 大佬,代码可以了,太厉害了!
详细的报错信息如下:
Caused by: java.lang.RuntimeException: java.lang.RuntimeException: Failed to create webview. at com.tencent.shadow.core.loader.delegates.ShadowActivityDelegate.onCreate(ShadowActivityDelegate.kt:159) at com.tencent.shadow.core.runtime.container.PluginContainerActivity.onCreate(PluginContainerActivity.java:85) at android.app.Activity.performCreate(Activity.java:7802) at android.app.Activity.performCreate(Activity.java:7791) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1299) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3245) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409) at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83) at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016) at android.os.Handler.dispatchMessage(Handler.java:107) at android.os.Looper.loop(Looper.java:214) at android.app.ActivityThread.main(ActivityThread.java:7356) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930) Caused by: java.lang.RuntimeException: Failed to create webview. at org.apache.cordova.CordovaWebViewImpl.createEngine(CordovaWebViewImpl.java:84) at org.apache.cordova.CordovaActivity.makeWebViewEngine(CordovaActivity.java:209) at org.apache.cordova.CordovaActivity.makeWebView(CordovaActivity.java:205) at org.apache.cordova.CordovaActivity.init(CordovaActivity.java:149) at org.apache.cordova.CordovaActivity.loadUrl(CordovaActivity.java:227) at com.example.hello.MainActivity.onCreate(MainActivity.java:39) at com.tencent.shadow.core.loader.delegates.ShadowActivityDelegate.onCreate(ShadowActivityDelegate.kt:156) at com.tencent.shadow.core.runtime.container.PluginContainerActivity.onCreate(PluginContainerActivity.java:85) at android.app.Activity.performCreate(Activity.java:7802) at android.app.Activity.performCreate(Activity.java:7791) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1299) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3245) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409) at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83) at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016) at android.os.Handler.dispatchMessage(Handler.java:107) at android.os.Looper.loop(Looper.java:214) at android.app.ActivityThread.main(ActivityThread.java:7356) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930) Caused by: java.lang.reflect.InvocationTargetException at java.lang.reflect.Constructor.newInstance0(Native Method) at java.lang.reflect.Constructor.newInstance(Constructor.java:343) at org.apache.cordova.CordovaWebViewImpl.createEngine(CordovaWebViewImpl.java:82) at org.apache.cordova.CordovaActivity.makeWebViewEngine(CordovaActivity.java:209) at org.apache.cordova.CordovaActivity.makeWebView(CordovaActivity.java:205) at org.apache.cordova.CordovaActivity.init(CordovaActivity.java:149) at org.apache.cordova.CordovaActivity.loadUrl(CordovaActivity.java:227) at com.example.hello.MainActivity.onCreate(MainActivity.java:39) at com.tencent.shadow.core.loader.delegates.ShadowActivityDelegate.onCreate(ShadowActivityDelegate.kt:156) at com.tencent.shadow.core.runtime.container.PluginContainerActivity.onCreate(PluginContainerActivity.java:85) at android.app.Activity.performCreate(Activity.java:7802) at android.app.Activity.performCreate(Activity.java:7791) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1299) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3245) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409) at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83) at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016) at android.os.Handler.dispatchMessage(Handler.java:107) at android.os.Looper.loop(Looper.java:214) at android.app.ActivityThread.main(ActivityThread.java:7356) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930) Caused by: java.lang.ClassCastException: android.webkit.WebViewClient cannot be cast to org.apache.cordova.engine.SystemWebViewClient at org.apache.cordova.engine.SystemWebView.setWebViewClient(SystemWebView.java:70) at com.tencent.shadow.core.runtime.ShadowWebView.init(ShadowWebView.java:82) at com.tencent.shadow.core.runtime.ShadowWebView.(ShadowWebView.java:61)