原生Android中嵌入Cordova Webview

Android實現(xiàn)在當(dāng)前進(jìn)程打開網(wǎng)頁可以將Cordova中的WebView嵌入Android項目中,實現(xiàn)簡單,不需要自己實現(xiàn),所以掌握如何嵌入WebView對項目快速開發(fā)很有幫助

官方也有這方面的教程操作,但最新版本的cordova android(4.0.0)對其代碼庫做了大的改動。這種變化,大多是一種設(shè)計模式,使得上面描述的方法不能正常工作。

本文將展示如何與cordova Android的新變化合作,嵌入cordova webview在本機(jī)Android應(yīng)用程序。

創(chuàng)建Cordova安卓項目

cordova create test_cordova com.example.hello HelloWorld
cordova platform add android
cordova plugin add nl.x-services.plugins.toast
cordova plugin add org.apache.cordova.device
cordova build

上面第三行和第四行是將其他的第三方插件也嵌入安卓原生工程使用

創(chuàng)建Android Native項目

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    public void startCordovaActivity(View view) {
        Intent intent = new Intent(this, TestCordovaActivity.class);
        startActivity(intent);
    }

    public void startCordovaActivityWithLayout(View view) {
        Intent intent = new Intent(this, TestCordovaWithLayoutActivity.class);
        startActivity(intent);
    }

}
  • startCordovaActivity 將轉(zhuǎn)移到一個新活動,其布局是以程序方式創(chuàng)建的cordova webview。
  • startCordovaActivity 將轉(zhuǎn)移到一個新的活動,其布局使用xml布局文件定義并嵌入cordova webview。

TestCordovaActivity

public class TestCordovaActivity extends CordovaActivity {

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        super.init();
        // Load your application
         launchUrl = "file:///android_asset/www/index.html";
//        launchUrl = "file:///android_asset/www/index2.html";
        loadUrl(launchUrl);
   }
}

不需要xml布局,加載的是index.html網(wǎng)頁

TestCordovaWithLayoutActivity

public class TestCordovaWithLayoutActivity extends CordovaActivity {


    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test_cordova_with_layout);
        super.init();
        // Load your application
        // launchUrl = "file:///android_asset/www/index.html"
        launchUrl = "file:///android_asset/www/index2.html";
        loadUrl(launchUrl);
    }

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

    @Override
    protected void createViews() {
        //Why are we setting a constant as the ID? This should be investigated
//        appView.getView().setId(100);
//        appView.getView().setLayoutParams(new FrameLayout.LayoutParams(
//                ViewGroup.LayoutParams.MATCH_PARENT,
//                ViewGroup.LayoutParams.MATCH_PARENT));
//
//        setContentView(appView.getView());

        if (preferences.contains("BackgroundColor")) {
            int backgroundColor = preferences.getInteger("BackgroundColor", Color.BLACK);
            // Background of activity:
            appView.getView().setBackgroundColor(backgroundColor);
        }

        appView.getView().requestFocusFromTouch();
    }

}

public class Main2Activity extends Activity implements CordovaInterface{
    private SystemWebView cordova_webview;
    private String TAG = "CORDOVA_ACTIVITY";
    private final ExecutorService threadPool = Executors.newCachedThreadPool();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
        cordova_webview = (SystemWebView) findViewById(R.id.cordova_web_view);
        //從4.x開始CordovaWebView不再是View的子類,用SystemWebView代替
        //下面這行代碼非常關(guān)鍵,如果沒有這行,的、diveceready就沒有執(zhí)行,顯灰色狀態(tài)
        cordova_webview.getSettings().setJavaScriptEnabled(true);
//        Config.init(this);
        String url = "file:///android_asset/www/index.html";
        cordova_webview.loadUrl(url);
    }

    @Override
    public void startActivityForResult(CordovaPlugin cordovaPlugin, Intent intent, int i) {
        Log.d(TAG, "setActivityResultCallback is unimplemented");
    }

    @Override
    public void setActivityResultCallback(CordovaPlugin cordovaPlugin) {
        Log.d(TAG, "startActivityForResult is unimplemented");
    }

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

    @Override
    public Object onMessage(String s, Object o) {
        Log.d(TAG, s);
        if (s.equalsIgnoreCase("exit")) {
            super.finish();
        }
        return null;
    }

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

使用setContentView顯式設(shè)置布局xml。需要重寫兩個方法:

  • makeWebView: 它使用R.id.cordovaWebView,在layout xml文件中定義
  • createViews : 我們重寫它只是因為它將默認(rèn)使用setContentView。但是我們想使用我們的xml布局,所以需要它。

activity_test_cordova_with_layout.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.example.jimmy.embeddedcordovawebviewdemo.TestCordovaWithLayoutActivity">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:background="#FF0000"
        android:textColor="#FFFFFF"
        android:gravity="center"
        android:text="This is native text view"
        />

    <org.apache.cordova.engine.SystemWebView
        android:id="@+id/cordovaWebView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />

</LinearLayout>

為了向后兼容,我們使用cordova庫中的org.apache.cordova.engine.SystemWebView,直到4.0.0之前也是可以使用org.apache.cordova.CordovaWebView

將Cordova Android項目復(fù)制到本機(jī)Android應(yīng)用程序

拷貝jar包

去Apache官方網(wǎng)站下載最新的cordova Android Packet,然后創(chuàng)建jar包。官方網(wǎng)站
下載好官方壓縮文件cordova-android-xxx.zip,解壓縮,通過ant工具導(dǎo)航到 /framework目錄下,執(zhí)行ant jar命令,如果提示
build fali, you need to create the file'local.properties' by running 'android update project -p .'命令,在cmd窗口執(zhí)行如上命令之后再次執(zhí)行ant jar
將會在當(dāng)前目錄生成cordova-4.0.0.jar
拷貝jar包到項目中,在build.gradle中添加依賴

compile files('libs/cordova-4.0.0.jar')

拷貝www目錄

目錄結(jié)構(gòu)如下
platforms/android/assets/www -> src/main/assets/www

拷貝插件

注意:拷貝platforms/android/src/目錄結(jié)構(gòu)下的所有文件,而不是plugins/下的所有文件。因為在運(yùn)行cordova build命令時,cordova將復(fù)制plugins/文件夾下的插件到目錄platforms/android/src/下,并執(zhí)行一些操作。

拷貝config.xml

注意:不要拷貝更目錄下的config.xml,要拷貝的是platforms下的config.xml
目錄結(jié)構(gòu)如下
platforms/android/res/xml/config.xml -> src/main/res/xml/

整個工程的目錄結(jié)構(gòu)如下圖所示:


若工程點擊事件報錯:
06-11 17:47:24.708 12895-12895/com.intbird.soft.cordoca I/chromium﹕ [INFO:CONSOLE(41)] “Refused to execute inline event handler because it violates the following Content Security Policy directive: “default-src ‘self’ data: gap: https://ssl.gstatic.com ‘unsafe-eval’”. Note that ‘script-src’ was not explicitly set, so ‘default-src’ is used as a fallback. “, source: file:///android_asset/www/index.html (41)
直接注釋掉 index.html meta 第一行,重新運(yùn)行

<html>
    <head>
        <!-- <meta http-equiv="Content-Security-Policy" content="default-src 'self' data: gap: https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *">
        -->
        <meta name="format-detection" content="telephone=no">
        <meta name="msapplication-tap-highlight" content="no">
        <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width">

        <link rel="stylesheet" type="text/css" href="css/index.css">
        <script type="text/javascript" charset="utf-8" src="cordova.js"></script>
        <script type="text/javascript" charset="utf-8" src="js/index.js"></script>
        <title>Hello World</title>

    </head>
    <body onload="onPageLoad()">
    <input type="button" onclick="btnStartActivity('web')" value="使用webView" class="button"/><br/>
    <input type="button" onclick="btnStartActivity('camera')" value="使用相機(jī)" class="button"/><br/>
    <input type="button" onclick="btnStartActivity('')" value="未處理" class="button"/>
    </body>
</html>

參考文獻(xiàn):

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容