11

I just upgraded to cordova 4.0 for android. I used the following post to load a cordova webview inside a fragment..

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

This code no longer works after upgrading to cordova 4.0 from 3.*

Specifically, an exception is throw on this 2nd line...

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

Where this tag is in my layout file...

 <org.apache.cordova.CordovaWebView
        android:layout_below="@+id/DialogTopBar"
        android:layout_width="match_parent"
        android:layout_height="fill_parent"
        android:id = "@+id/myWebView"
        />

Exception message...

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

Does anyone have any ideas on how to get around this?

It does look like since cordova 4.0, the CordovaWebView class was changed from..

public class CordovaWebView extends WebView

to

public interface CordovaWebView
TWilly
  • 4,863
  • 3
  • 43
  • 73

3 Answers3

8

Not sure if this is correct, but I got it working by copying some of the code from the new 4.0 CordovaActivity.java file into my fragment to setup the CordovaWebView manually.

Step 1. Remove CordovaWebView xml tag in layout.

Step 2. Add in following code to fragment to manually create CordovaWebView and inject it into fragment.

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());
}
TWilly
  • 4,863
  • 3
  • 43
  • 73
4

I had the same problem and I have resolved it as show below. In the first example, I embed a CordovaWebView inside an activity. Be careful with cordova 4.0 we can't include a CordovaWebView inside our layouts, so in previous cordova versions CordovaWebView extends WebView but since Cordova 4 this is an interface, so we have to include a org.apache.cordova.engine.SystemWebView. If you see the code you can see that you have to override the methods makeWebView() and createViews() that are called through super.init().

Example 1: Cordova inside an Activity

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_width="match_parent"
        android:layout_height="match_parent">

        <org.apache.cordova.engine.SystemWebView
            android:id="@+id/cordovaWebView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            />
    </LinearLayout>
J.Arroyo
  • 176
  • 6
  • this opens me a full screen default browser, instead loading the url in the view inside the app. – narancs May 24 '17 at 18:09
0

I found a way to do this here: http://www.catharinegeek.com/embed-cordova-webview-in-android-native-app/

the trick is using SystemWebView in layout xml

 <org.apache.cordova.engine.SystemWebView
        android:id="@+id/cordovaView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
  • https://web.archive.org/web/20190420150819/www.catharinegeek.com/embed-cordova-webview-in-android-native-app/ – Dr Deo Sep 26 '20 at 06:55