將cordova集成到Android studio的最佳方法

網上有不少集成cordova到Android studio中進行Android開發的方法,這裏我給你們介紹一種比較簡單的方法,親測有效。html

目的

首先咱們明確目的,咱們但願把cordova快速集成到Android studio中,爲了之後的複用,咱們但願作成jar或者aar,能夠用於之後的項目,目的明確了,後面就一步一步來吧。java

cordova相關代碼

代碼哪裏來?你們不須要找,請看這裏,將代碼clone下來後發現有這麼幾個咱們要用的文件夾:android

  • cordova-js-src:這部分是cordova-android對應的js代碼,混合開發的時候H5須要將這個文件夾導入web工程,並作相應的引用和配置
  • framework:這部分是cordova-android部分代碼,須要所有拿過來
  • test:這部分是測試工程,咱們在集成好cordova後,還要根據測試工程實例進行相關配置,才能徹底集成cordova到Android studio中進行hybrid開發。

開始集成

  1. 直接把framework模塊打一個aar或jar包(我打的是aar);
  2. 把cordova-js-src複製到web工程中;
  3. 結束。 臥槽?這麼簡單?別激動,還沒完,繼續往下看。

融合cordova到本身的工程中

首先,咱們建一個本身的Android工程,而後咱們複製test工程中的/res/xml/config.xml文件到咱們本身工程的/res/xml/config.xml中,不要改路徑,而後修改config.xml文件:git

<?xml version='1.0' encoding='utf-8'?>
<widget
    id="your package name"    //包名
    version="0.0.1">          //版本號
    <content src="index.html" />
    <feature name="xxxxx">    //插件名
        <param
            name="android-package"
            value="your package name.xxxxx" />  //插件路徑
        <param
            name="onload"
            value="true" />
    </feature>
    <preference
        name="loglevel"
        value="DEBUG" />
    <preference
        name="useBrowserHistory"
        value="true" />
    <preference
        name="exit-on-suspend"
        value="false" />
    <preference
        name="showTitle"
        value="true" />
</widget>

極其重要的信息我已經作了註釋,我想你們都能看懂,那就沒問題了。這個配置文件是極其重要的,必需要有,切記切記!github

至此,集成就結束了。那麼如何開發?我簡單講一下native這邊須要作什麼。web

  • Plugin:你們在上文中能夠看到插件的配置,那麼插件是什麼?其實就是cordova提供給native和js通訊的管道,咱們須要本身實現一個插件類,參考這裏
  • AllowBridgeAccess:在插件類中,咱們須要:
@Override
    public Boolean shouldAllowBridgeAccess(String url) {
        return true;
    }

這樣咱們的插件才能夠被容許做爲bridge(生效)。apache

  • Lifecycle:爲了後續佈局的擴展,我沒有選擇extend CordovaActivity,那麼我須要模仿CordovaActivity處理相關生命週期,這裏個人佈局很簡單:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/exam_home"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

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

</LinearLayout>

而後咱們看activity中的代碼:ide

@ContentView(R.layout.activity_exam)
public class ExamActivity extends BaseFragmentActivity {
    private static final String EXAM_CENTER_URL = "";
    //測試環境url
    private static final String EXAM_CENTER_URL_TEST = "";
    private static final String ERROR_URL = "file:///android_asset/404.html";
    @InjectView(R.id.cordovaWebView)
    protected SystemWebView webView;
    @InjectView(R.id.exam_home)
    protected LinearLayout examHome;
    private CordovaWebView cordovaWebView;
    protected CordovaInterfaceImpl cordovaInterface;
    private LoadingDialogFragment loading;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        init();
    }

    private void init() {
        setTitle(R.string.drawer_examination);
        loading = LoadingDialogFragment.newInstance(false, getString(R.string.loading));
        loading.setCancelable(false);
        initWebView();
        loadExamCenterUrl();
    }

    private void initWebView() {
        ConfigXmlParser parser = new ConfigXmlParser();
        parser.parse(getActivity());
        cordovaInterface = new CordovaInterfaceImpl(getActivity()) {
            @Override
            public Object onMessage(String id, Object data) {
                if ("onPageStarted".equals(id)) {
                    showRequestLoading();
                    return true;
                }
                if ("onPageFinished".equals(id)) {
                    hideRequestLoading();
                    return true;
                }
                if ("onReceivedError".equals(id)) {
                    cordovaWebView.loadUrl(ERROR_URL);
                    return true;
                }
                return super.onMessage(id, data);
            }
        };
        if (NetworkUtils.isNetworkConnected(getActivity())) {
            webView.getSettings().setCacheMode(WebSettings.LOAD_DEFAULT);
        } else {
            webView.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
        }
        cordovaWebView = new CordovaWebViewImpl(new SystemWebViewEngine(webView));
        if (!cordovaWebView.isInitialized()) {
            cordovaWebView.init(cordovaInterface, parser.getPluginEntries(), parser.getPreferences());
        }
    }

    private void loadExamCenterUrl() {
        if (AppConfig.isApkInDebug()) {
            cordovaWebView.loadUrl(getExamCenterUrl(EXAM_CENTER_URL_TEST));
        } else {
            cordovaWebView.loadUrl(getExamCenterUrl(EXAM_CENTER_URL));
        }
    }

    private String getExamCenterUrl(String initUrl) {
        return "http://www.baidu.com";
    }

    private void hideRequestLoading() {
        synchronized (loading) {
            loading.dismiss();
        }
    }

    private void showRequestLoading() {
        synchronized (loading) {
            loading.show(getSupportFragmentManager());
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (cordovaWebView != null) {
            cordovaWebView.handleResume(true);
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (cordovaWebView != null) {
            cordovaWebView.handlePause(true);
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        examHome.removeView(webView);
        webView.removeAllViews();
        if (cordovaWebView != null) {
            cordovaWebView.handleDestroy();
        }
    }

    @Override
    protected void onStart() {
        super.onStart();
        if (cordovaWebView != null) {
            cordovaWebView.handleStart();
        }
    }

    @Override
    protected void onStop() {
        super.onStop();
        if (cordovaWebView != null) {
            cordovaWebView.handleStop();
        }
    }
}

能夠看出,這裏對聲明週期的處理模仿了CordovaActivity的生命週期,同時對基本native加載流程作了簡單處理。尤爲onDestory中的處理能夠避免報webview.destory()的錯誤。這段代碼適用於任何一個沒有extend CordovaActivity進行cordova開發的activity。佈局

還有最最重要的一點:在正式打包apk的時候,必定要記得,在proguard-rules.pro文件中,去掉插件類的混淆,不能混淆插件類,不然打出來release包以後,進入混合開發的activity,會讓你崩到爽……測試

OK,就是這樣了,有什麼疑問歡迎你們交流。

相關文章
相關標籤/搜索