将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,就是这样了,有什么疑问欢迎你们交流。

相关文章
相关标签/搜索