Cordova 4.0 上的 Android 片段内的 Cordova webview

Posted

技术标签:

【中文标题】Cordova 4.0 上的 Android 片段内的 Cordova webview【英文标题】:Cordova webview inside Android Fragment on Cordova 4.0 【发布时间】:2015-08-09 22:26:45 【问题描述】:

我刚刚升级到适用于 android 的 cordova 4.0。我使用以下帖子在片段中加载了cordova webview..

https://github.com/Adobe-Marketing-Cloud-Apps/app-sample-android-phonegap/wiki/Embed-Webview-in-Android-Fragment

从 3.* 升级到 cordova 4.0 后,此代码不再有效

具体来说,第二行抛出异常...

LayoutInflater localInflater = inflater.cloneInContext(new CordovaContext(getActivity(), this));
View v = localInflater.inflate(R.layout.dialog_webview, container, false);

这个标签在我的布局文件中的位置...

 <org.apache.cordova.CordovaWebView
        android:layout_below="@+id/DialogTopBar"
        android:layout_
        android:layout_
        android:id = "@+id/myWebView"
        />

异常消息...

android.view.InflateException: Binary XML file line #43: Class is not a View org.apache.cordova.CordovaWebView

有人对如何解决这个问题有任何想法吗?

看起来确实是从 cordova 4.0 开始,CordovaWebView 类从..改变了。

public class CordovaWebView extends WebView

public interface CordovaWebView

【问题讨论】:

【参考方案1】:

不确定这是否正确,但我通过将新的 4.0 CordovaActivity.java 文件中的一些代码复制到我的片段中以手动设置 CordovaWebView 来使其工作。

步骤 1. 移除布局中的 CordovaWebView xml 标签。

步骤 2. 在片段中添加以下代码以手动创建 CordovaWebView 并将其注入片段中。

private CordovaWebView webView;

// Read from config.xml:
protected CordovaPreferences preferences;
protected String launchUrl;
protected ArrayList<PluginEntry> pluginEntries;
protected CordovaInterfaceImpl cordovaInterface;


protected void loadConfig() 
    ConfigXmlParser parser = new ConfigXmlParser();
    parser.parse(getActivity());
    preferences = parser.getPreferences();
    preferences.setPreferencesBundle(getActivity().getIntent().getExtras());
    preferences.copyIntoIntentExtras(getActivity());
    launchUrl = parser.getLaunchUrl();
    pluginEntries = parser.getPluginEntries();
    // Config.parser = parser;


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) 

    LayoutInflater localInflater = inflater.cloneInContext(new CordovaContext(getActivity(), this));

    View v = localInflater.inflate(R.layout.dialog_webview, container, false);

    cordovaInterface =  new CordovaInterfaceImpl(getActivity());
    if(savedInstanceState != null)
        cordovaInterface.restoreInstanceState(savedInstanceState);

    loadConfig();

    webView = new CordovaWebViewImpl(CordovaWebViewImpl.createEngine(getActivity(), preferences));

    webView.getView().setId(100);
    RelativeLayout.LayoutParams wvlp = new RelativeLayout.LayoutParams(
            RelativeLayout.LayoutParams.MATCH_PARENT,
            RelativeLayout.LayoutParams.FILL_PARENT);
    wvlp.addRule(RelativeLayout.BELOW,R.id.DialogTopBar);
    webView.getView().setLayoutParams(wvlp);

    if (!webView.isInitialized()) 
        webView.init(cordovaInterface, pluginEntries, preferences);
    
    cordovaInterface.onCordovaInit(webView.getPluginManager());
    // webView = (SystemWebView)v.findViewById(R.id.myWebView);

    // Config.init(getActivity());
    ((RelativeLayout)v).addView(webView.getView());

【讨论】:

您是否找到任何其他方法或解决方法? 这对我也有用,但有点乱。 :) 还有其他人有这个问题吗? 他们做了这样一个 PITA 来嵌入一个 Cordova 网络视图,呸 你们找到其他方法了吗?【参考方案2】:

我遇到了同样的问题,我已经解决了,如下所示。在第一个示例中,我在活动中嵌入了 CordovaWebView。注意cordova 4.0,我们不能在布局中包含CordovaWebView,所以在以前的cordova 版本中CordovaWebView 扩展了WebView,但是由于Cordova 4 这是一个接口,所以我们必须包含一个org.apache.cordova.engine.SystemWebView。如果您看到代码,您可以看到您必须覆盖通过 super.init() 调用的方法 makeWebView() 和 createViews()。

示例 1:Activity 中的 Cordova

MainActivity.java

public class MainActivity extends CordovaActivity
        @Override
        public void onCreate(Bundle savedInstanceState)
        
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);       

            super.init();
            // Load your application
            launchUrl = "file:///android_asset/www/index.html"
            loadUrl(launchUrl);

        

        @Override
        protected CordovaWebView makeWebView() 
            SystemWebView webView =SystemWebView)findViewById(R.id.cordovaWebView);
            return new CordovaWebViewImpl(new SystemWebViewEngine(webView));
        

        @Override
        protected void createViews()          
            appView.getView().requestFocusFromTouch();
        
    

activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
        <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical" android:layout_
        android:layout_>

        <org.apache.cordova.engine.SystemWebView
            android:id="@+id/cordovaWebView"
            android:layout_
            android:layout_
            />
    </LinearLayout>

【讨论】:

这会打开一个全屏默认浏览器,而不是在应用程序内的视图中加载 url。【参考方案3】:

我在这里找到了一种方法: http://www.catharinegeek.com/embed-cordova-webview-in-android-native-app/

诀窍是在布局 xml 中使用 SystemWebView

 <org.apache.cordova.engine.SystemWebView
        android:id="@+id/cordovaView"
        android:layout_
        android:layout_ />

【讨论】:

web.archive.org/web/20190420150819/www.catharinegeek.com/…

以上是关于Cordova 4.0 上的 Android 片段内的 Cordova webview的主要内容,如果未能解决你的问题,请参考以下文章

在MAC上搭建cordova3.4.0的IOS和android开发环境

Cordova 4.0 config.xml 中的 Android 权限

Phonegap/Cordova Geolocation 不适用于 Android 4.0+,但适用于所有其他平台

不使用支持库的 Android 4.0、4.1 (<4.2) 中嵌套片段的最佳实践

Cordova Android 6.4.0 创建 res 文件夹顶层不在平台 android 内

片段还是支持片段?