屁话
现在移动端大部分都不采用纯原生开发了,基本上混合开发居多或者直接采用UniApp
、React Native
、Flutter
等等,也有很多采用JSBridge
技术,很多人不太理解这个东西,专业术语我就不解释了,这么说吧他其实就是通过特定的数据结构的方式通过原生和JS的交互从而实现的一个东西,他是一个较为广泛的概念。其中你知道的最大的使用JSBridge
技术的App就是微信,小程序就是通过这类技术实现的。微信原生封装各种插件给你使用,然后你前端使用特定的方式去跟原生交互从而实现js和原生的互相调用。
Cordova简介
下面介绍下Cordova,他会让你更加方便的实现跨平台开发
Cordova(原名PhoneGap)是一种移动开发框架,它允许开发者使用Web技术(HTML、CSS和JavaScript)来创建跨平台的移动应用程序。Cordova提供了一种将Web应用打包成原生应用的方式,使开发者可以在多个平台上构建一次,然后在iOS、Android、Windows Phone等平台上运行。以下是Cordova框架的主要特点:
跨平台开发: Cordova允许开发者在一次代码编写后,将应用打包成适用于多个平台的原生应用。这样,开发者可以避免重复编写不同平台的代码,节省开发时间和精力。
基于Web技术: Cordova应用程序使用Web技术进行开发,包括HTML、CSS和JavaScript。这使得前端开发者可以直接利用自己的技能来开发移动应用。
插件扩展: Cordova提供了丰富的插件,允许开发者在应用程序中使用设备功能,如相机、地理位置、推送通知等。开发者还可以自己开发插件,以满足应用的特定需求。
轻量级: Cordova应用程序相对于原生应用来说比较轻量级,因为它们是基于Web技术运行的。这使得应用的安装包大小相对较小,运行性能也相对较好。
社区支持: Cordova有一个庞大的开发者社区,提供了丰富的文档、教程和插件,帮助开发者解决问题和提高开发效率。
虽然Cordova框架提供了许多优点,但它也有一些限制。由于Cordova应用是基于Web技术运行的,相比原生应用可能会有一些性能上的差异。此外,Cordova应用对于某些高级原生功能可能需要使用插件进行扩展。
总体而言,Cordova是一种适用于轻量级跨平台移动应用开发的框架。它适用于一些简单的应用场景,如企业内部应用、信息类应用等。对于复杂的应用场景或对性能要求较高的应用,可能需要考虑原生开发或其他更为高级的跨平台框架。
官方的部分源码地址,其他的可以在github上搜
android
https://github.com/apache/cordova-android
iOS
https://github.com/apache/cordova-ios
废话不多说直接接入,因为很多资料网上都可以搜到
Cordova接入
下文中的cordova-base
为Cordova项目根目录名,你可以随便起,当然你运行脚本的时候要一致, cordova-vue
是前端vue3的项目名,你可以随便起,但是也是运行脚本的时候注意一致
首先安装npm,不说了
安装cordova
npm install -g cordova
创建cordova项目
cordova create cordova-base com.casic.titan.cordova cordova-base
上面的cordova-base
,是项目和和文件夹名,默认保持一致即可
添加Android平台
cd cordova-base
切换到刚才创建的项目文件夹下
cordova platform add android
添加Android平台
初始化vue环境和创建vue项目
在cordova项目根目录下执行命令(下面命令好像创建的是vue2)
npm install -g vue
npm install -g vue-cli
创建vue2项目
vue init webpack cordove-vue
其中cordove-vue是vue项目名
创建vue3项目
vue create cordove-vue
其中cordove-vue是vue项目名
修改vue项目的配置
进入vue项目下,修改Vue项目config/index.js文件。
vue2修改config/index.js文件中build下的:
index: path.resolve(__dirname, '../../www/index.html'),
// Paths
assetsRoot: path.resolve(__dirname, '../../www'),
assetsSubDirectory: 'static',
assetsPublicPath: '',
vue3修改vue.config.js文件下的:
添加:
lintOnSave: false,
publicPath: '/',
outputDir: '../www',
assetsDir: 'static',
indexPath: 'index.html',
runtimeCompiler: false,
productionSourceMap: false,
编译vue项目
在vue项目目录下执行:npm run build
,也就是上面创建的目录:cordova-vue
检查Android环境,需要下载jdk、Android sdk、gradle等,建议直接下载Android Studio
cordova requirements
命令可以检查环境
将vue和cordova运行到Android环境
在cordova项目根目录下运行:cordova run android
,也就是cordova-base目录(cordova-vue的上级)
修改vue项目后同步安卓环境
需要修改的话需要重新再cordova-vue
目录下执行npm run build
命令和在cordova-base
目录下执行cordova prepare
新增插件,比如调用摄像头:
执行命令:cordova plugin add cordova-plugin-camera
然后就自动完事了
然后再vue项目下的index.html
中添加,vue2和vue3路径有些区别
<script type="text/javascript" src="cordova.js"></script>
这个插件就可以使用了,具体用法可以搜索具体插件的用法
移除插件
执行命令:cordova plugin remove cordova-plugin-camera
cordova-plugin-camera
为插件名
编写自定义插件
新建个文件夹存储你的自定义插件
为了方便肯定我们自定义插件不止一个,因此我们可以新建一个总文件夹:native-plugin
(名字随意),这个文件夹可以随便在哪,建议在Cordova根目录下,方便管理
安装plugman
运行脚本npm install -g plugman
等待就完事了,安装完成后可以通过plugman -v
查看版本,是否安装成功
plugman创建插件
命令:plugman create --name [插件名] --plugin_id [插件ID] --plugin_version [插件版本号]
例子:plugman create --name plugin-toast --plugin_id plugin-toast --plugin_version 1.0.0
新建Android目录
上面命令执行完后会再native-plugin
下生成一个plugin-toast
文件夹,打开进入src下新建文件夹:android
,名字不可以修改
编写插件
随便在Android Studio中新建一个类ToastPlugin
继承CordovaPlugin
CordovaPlugin
一共三个excute
方法,看情况自行重写其中一个即可
public class ToastPlugin extends CordovaPlugin {
@Override
public boolean execute(String action, CordovaArgs args, CallbackContext callbackContext) throws JSONException {
if (Plugin.PluginAction.TOAST.equals(action)) {
if (args == null || TextUtils.isEmpty((String) args.get(0))) {
return super.execute(action, args, callbackContext);
}
Toast.makeText(cordova.getContext(), (String) args.get(0), Toast.LENGTH_SHORT).show();
return true;
}
return super.execute(action, args, callbackContext);
}
}
配置plugin.xml
打开插件中的plugin.xml
文件夹,修改配置,相关配置都有备注,关于plugin.xml
相关配置解释可以自行搜索
配置中的ToastPlugin
即上面的类名,建议保持一致,这样减少容错率
<?xml version='1.0' encoding='utf-8'?>
<plugin id="plugin-toast" version="1.0.0" xmlns="http://apache.org/cordova/ns/plugins/1.0" xmlns:android="http://schemas.android.com/apk/res/android">
<name>plugin-toast</name>
<js-module name="plugin-toast" src="www/plugin-toast.js">
<clobbers target="cordova.plugins.plugin-toast" />
</js-module>
<!--添加Android平台 -->
<platform name="android">
<config-file target="res/xml/config.xml" parent="/*">
<!-- JS调用时的前缀名字 -->
<feature name="ToastPlugin">
<!-- 插件类名全路径 -->
<param name="android-package" value="org.apache.cordova.toast.ToastPlugin"/>
</feature>
</config-file>
<!-- 意思从Android目录下找到ToaPlugin.java文件,拷贝到工程项目中的toa包下,包名要与上面的插件类名全路径对应上 -->
<source-file src="src/android/ToastPlugin.java" target-dir="src/org/apache/cordova/toast" />
<source-file src="src/android/ToastPluginAction.java" target-dir="src/org/apache/cordova/toast" />
<!-- android specific notification apis -->
<js-module src="www/android/toast.js" name="toast_android">
<merges target="toast" />
</js-module>
</platform>
</plugin>
初始化插件
在插件根目录plugin-toast下执行:npm init
添加自定义插件
在Cordova项目根目录cordova-base
下,执行cordova plugin add 插件的绝对路径/native-plugin/plugin-toast
注意是绝对路径
调用自定义插件
<template>
<div>
<input type="text" class="custom-input" placeholder="请输入内容" v-model="toastInfo" />
<p><button @click="toast">吐司提示</button></p>
</div>
</template>
<script>
import { defineComponent } from "vue";
export default defineComponent({
data() {
return {
toastInfo: "默认提示内容",
};
},
methods: {
toast() {
cordova.exec(this.onSuccess, this.onFailed, "ToastPlugin", "toast", [this.toastInfo]);
},
onSuccess(deviceInfo) {
console.log("toast插件调用成功");
},
onFailed(message) {
alert("Failed : " + message);
},
},
});
</script>
<style>
.custom-input {
padding: 10px;
border: 1px solid #ccc;
border-radius: 5px;
outline: none;
font-size: 16px;
color: #333;
width: 300px;
}
.custom-input::placeholder {
color: #999;
}
</style>
请求插件统一方法:
cordova.exec(onSuccess, onFailed, "插件类名", "方法名", [参数]);
onSuccess
请求成功回调方法
onFailed
请求失败回调方法
插件类名
一般为插件包下src
中android
下以plugin结尾的类(也就是继承CordovaPlugin的类),例如:AppAbilityPlugin
方法名
这个插件提供的插件的提供方法,例如getAppName
,在src
中android
文件夹下以Action结尾,例如:AppAbilityPluginAction
,部分没有单独文件就在AppAbilityPlugin
中寻找
参数
请求插件所需参数,[ ]
代表数组,{ }
代表对象具体看插件方法需求