在更大的应用程序中嵌入CordovaWebView(Cordova版本5.2.0)

时间:2015-08-26 00:46:43

标签: android cordova

我们有一个基于Android的{​​{1}}应用程序。该应用程序不使用Cordova 3.5,而是通过创建CordovaActivity并将其嵌入应用程序中来工作。当我最初构建这个应用程序时,我很难在应用程序中实例化并初始化CordovaWebView,我写了this question寻求帮助。我获得了this link有关获取此设置的说明。我遵循了说明并使应用程序正常工作,尽管我确实需要偏离给出的指令,因为在我们的例子中,javascripts必须从远程服务器而不是从Android项目的/ assets / www文件夹加载。

以下是我为CordovaWebView实施主要活动的方式:

Cordova 3.5

请注意,我仅在此处显示与import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import android.app.Activity; import android.content.Intent; import android.content.res.Configuration; import android.os.Bundle; import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentManager; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.webkit.WebSettings; import android.webkit.WebView; import android.widget.FrameLayout; import android.widget.Toast; import org.apache.cordova.*; public class MobileForms extends FragmentActivity implements CordovaInterface, RetryDialogListener, EditServerDialogListener { protected FrameLayout webViewPlaceholder; protected MobileformsPreferences preferences; protected CordovaWebView cwv; protected CordovaPlugin activityResultCallback = null; protected boolean activityResultKeepRunning; protected final ExecutorService threadPool = Executors.newCachedThreadPool(); @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); preferences = new MobileformsPreferences(getApplicationContext()); setContentView(R.layout.main); initializeUI(); org.apache.cordova.Config.init(this); navigateToMobileforms(); } protected void initializeUI() { webViewPlaceholder = ((FrameLayout)findViewById(R.id.webViewPlaceholder)); // Initialize the WebView if necessary if (cwv == null) { // Create the webview cwv = new CordovaWebView(this); cwv.getSettings().setJavaScriptEnabled(true); cwv.getSettings().setGeolocationEnabled(true); cwv.getSettings().setJavaScriptCanOpenWindowsAutomatically(true); cwv.getSettings().setBuiltInZoomControls(false); cwv.getSettings().setSupportZoom(false); cwv.getSettings().setDomStorageEnabled(true); cwv.setWebViewClient(new CordovaWebViewClient(this, cwv) { @Override public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) { try { view.stopLoading(); } catch (Exception e) {} if (view.canGoBack()) { view.goBack(); } view.loadUrl("about:blank"); Toast.makeText(MobileForms.this, "Cannot connect. Please check your internet connection.", Toast.LENGTH_LONG).show(); Thread thread = new Thread() { @Override public void run() { try { Thread.sleep(3500); // As I am using LENGTH_LONG in Toast showRetryDialog(); } catch (Exception e) { e.printStackTrace(); } } }; thread.start(); } }); cwv.setWebChromeClient(new CordovaChromeClient(this, cwv) {}); // Application cache cwv.getSettings().setDomStorageEnabled(true); cwv.getSettings().setAppCachePath(getApplicationContext().getCacheDir().getAbsolutePath()); //"/data/data/"+ getPackageName() +"/cache"); cwv.getSettings().setAppCacheEnabled(true); cwv.getSettings().setAppCacheMaxSize(1024*1024*20); cwv.getSettings().setCacheMode(WebSettings.LOAD_DEFAULT); } // Attach the WebView to its placeholder webViewPlaceholder.addView(cwv); } protected void navigateToMobileforms() { String serverName = preferences.getServerName(); if (serverName != null) { cwv.loadUrl(buildUrl(serverName)); } else { showServerEditDialog(); } } protected String buildUrl(String serverText) { return "http://"+serverText+"/path/to/index.php"; } protected void showRetryDialog() { FragmentManager fm = getSupportFragmentManager(); RetryDialogFragment retryDialog = new RetryDialogFragment(); retryDialog.show(fm, "retry_dialog"); } @Override public void onConfigurationChanged(Configuration newConfig) { // Remove the WebView from the old placeholder if (cwv != null) { webViewPlaceholder.removeView(cwv); } super.onConfigurationChanged(newConfig); // Load the layout resource for the new configuration setContentView(R.layout.main); // Reinitialize the UI initializeUI(); } @Override public Activity getActivity() { return this; } /** * Launch an activity for which you would like a result when it finished. When this activity exits, * your onActivityResult() method is called. * * @param command The command object * @param intent The intent to start * @param requestCode The request code that is passed to callback to identify the activity */ public void startActivityForResult(CordovaPlugin command, Intent intent, int requestCode) { this.activityResultCallback = command; // Start activity super.startActivityForResult(intent, requestCode); } @Override /** * Called when an activity you launched exits, giving you the requestCode you started it with, * the resultCode it returned, and any additional data from it. * * @param requestCode The request code originally supplied to startActivityForResult(), * allowing you to identify who this result came from. * @param resultCode The integer result code returned by the child activity through its setResult(). * @param data An Intent, which can return result data to the caller (various data can be attached to Intent "extras"). */ protected void onActivityResult(int requestCode, int resultCode, Intent intent) { super.onActivityResult(requestCode, resultCode, intent); CordovaPlugin callback = this.activityResultCallback; if (callback != null) { callback.onActivityResult(requestCode, resultCode, intent); } } @Override public ExecutorService getThreadPool() { return threadPool; } @Override public Object onMessage(String id, Object data) { // TODO Auto-generated method stub return null; } @Override public void onSettings() { MobileForms.this.showServerEditDialog(); } ... Code snipped ... } 实施相关的代码。

现在问题是我们需要将此代码带到最新版本的Cordova(版本5.2.0),我很难将此代码转换为最新版本,因为它似乎很多自版本3.5.0起,Cordova代码的重组已经发生。例如,此行现在不再有效:

Cordova

因为cwv = new CordovaWebView(this); 现在是一个接口,而不是一个类。

我已经看到updated instructions用于在更大的应用内部实现CordovaWebView作为webview,但我也在努力思考现在{{1}中的所有类和接口以及它们如何组合在一起。例如,CordovaCordovaCordovaWebViewCordovaWebViewImplSystemWebView

我很感激在解释不同类如何组合在一起和/或将我上面复制的代码移植到CordovaWebViewEngine时提供的任何帮助。

1 个答案:

答案 0 :(得分:1)

CordovaWebView不再是View了。您必须实例化保存视图的CordovaWebViewImpl,然后在其上调用getView()以检索视图。

以下是CordovaView,它是嵌入CordovaWebViewImpl的视图。您可以使用它代替旧的CordovaWebView

public class CordovaView extends FrameLayout {

    private CordovaWebViewEngine cordovaEngine;
    private CordovaWebView cordovaWebView;

    public CordovaView(Context context) {
        super(context);

        ConfigXmlParser parser = new ConfigXmlParser();
        parser.parse(context);
        CordovaPreferences preferences = parser.getPreferences();
        ArrayList<PluginEntry> pluginEntries = parser.getPluginEntries();

        cordovaEngine = CordovaWebViewImpl.createEngine(context, preferences);
        cordovaWebView = new CordovaWebViewImpl(cordovaEngine);
        cordovaWebView.init(new CordovaContext(context), pluginEntries, preferences);
        View webView = cordovaWebView.getView();
        addView(webView);
    }

    public WebView getWebView() {
        View view = cordovaWebView.getView();
        if (!(view instanceof WebView))
            throw new IllegalStateException("unexpected view type");
        return (WebView)view;
    }

    public void setInitialScale(int scale) {
        getWebView().setInitialScale(scale);
    }

    private class CordovaContext implements CordovaInterface {

        private final Activity activity;
        private final ExecutorService threadPool = Executors.newCachedThreadPool();

        public CordovaContext(Context context) {
            if (!(context instanceof Activity))
                throw new IllegalArgumentException("Context must be an Activity");
            activity = (Activity)context;
        }

        @Override
        public void startActivityForResult(CordovaPlugin command, Intent intent, int requestCode) {
        }

        @Override
        public void setActivityResultCallback(CordovaPlugin plugin) {
        }

        @Override
        public Activity getActivity() {
            return activity;
        }

        @Override
        public Object onMessage(String id, Object data) {
            return null;
        }

        @Override
        public ExecutorService getThreadPool() {
            return threadPool;
        }

        @Override
        public void requestPermission(CordovaPlugin plugin, int requestCode, String permission) {
        }

        @Override
        public void requestPermissions(CordovaPlugin plugin, int requestCode, String[] permissions) {
        }

        @Override
        public boolean hasPermission(String permission) {
            return false;
        }
    }
}