最近刚接触cordova+ionic,踩了不少坑。这里全是每次被报错卡住的时候,从河里摸出来的石头路。虽然网上都能查,但都是东一下西一下,做个笔记备忘。
npm install
安装cordova、ionic
ionic模板
ionic start MyIonicProject tabs --type=ionic-angular
运行web开发环境
ionic serve
//到此为止和之前用vue做web端的节奏一样,边查angular和ionic的文档边做
添加cordova安卓平台支持
ionic cordova platform add android
安装jdk
自动同时安装jre。确认java -version
和javac -version
正常。
设置jdk环境变量
JAVA_HOME
:C:\Program Files\Java\jdk1.8.0_231
(JDK具体路径)
Path
:加上 %JAVA_HOME%\bin
和 %JAVA_HOME%\jre\bin
安装android studio
提示缺少android sdk,选cancel继续,会自动安装sdk
安装gradle
官网 services.gradle.org/distributions/
选择版本下载,下载完解压即可
设置gradle环境变量
GRADLE_HOME
:D:\gradle-6.0-bin\gradle-6.0
(gradle具体路径)
Path
:加上 %GRADLE_HOME%\bin
设置Android SDK licences
用cmd进入C:\Users\36473\AppData\Local\Android\Sdk\tools\bin
运行
sdkmanager --licenses
全部选y
打包APK
ionic cordova build android
目录:platforms\android\app\build\outputs\apk\debug
运行Android studio
提示SDK not found
:根据提示点击自动修复
添加虚拟设备:在`select a system image里下载一个system image
提示VT-x is disabled in BIOS
:重启进入BIOS,关键字Intel Virtualization Technology
提示Not enough space to create userdata partition
:虚拟设备各种内存改小
虚拟机相关目录:
Users\36473\.android\avd
AppData\Local\Temp\AndroidEmulator
添加cordova 浏览器平台支持
ionic cordova platform add browser
安装native-run
尝试ionic cordova run browser
的时候报错
[ERROR] native-run was not found on your PATH. Please install it globally:
安装
npm i -g native-run
浏览器下运行cordova
ionic cordova run browser
ionic serve 与 ionic run browser的区别:
Ionic serve
: runs your app as a website (meaning it doesn't have any Cordova capabilities);
ionic run browser
: runs your app in the Cordova browser platform, which will inject cordova.js and any plugins that have browser capabilities。
关于cordova-plugin
在ionic cordova platform add android
的时候会顺带装了几个插件,比如cordova-plugin-device
等等,具体看package.json
,所以有了的就不用再装了。
还有个问题,有时候add
某个cordova-plugin
后会影响到其他依赖,需要重新安装依赖才行,目前还不知道是什么原因。
一个坑:为了解决某些网络问题,添加了cordova-plugin-advanced-http
这个插件,它还自动装了cordova-plugin-file
这个插件。后来发现不顶用,就用cordova plugin remove
命令把它们移除了。但后来导致打包的.apk
在Android studio
里跑不起来了。最后发现原因是移除插件的时候,在platform/android
目录下还有这两个插件的残留,把整个文件夹删了,再重新ionic cordova platform add browser
就好了。
安装并引用ionic-native/device
npm install --save @ionic-native/device@4
import { Device } from '@ionic-native/device';
...
providers: [
...
Device
]
import { Device } from '@ionic-native/device';
constructor(private device: Device) { }
...
console.log('Device UUID is: ' + this.device.uuid);
http请求跨域问题(开发环境)
首先确保用上这个组件
import { HttpClient } from "@angular/common/http";
...
constructor( public http: HttpClient) {
}
然后到ionic.config.json
中添加代理配置:
"proxies":[
{
"path": "/api",
"proxyUrl":"(具体请求域名)/api"
}
]
完成后重启项目,就能用/api代理请求了
IonicPage懒加载
参考文章:
https://www.jianshu.com/p/2c95e0fa4cc6
1.给需要懒加载的页面配置module.ts;
2.在对应页面的.ts文件里增加@IonicPage()特性;
3.在app.module.ts移除页面引用;
4.使用:不需要进行import导入,只需要将页面名字用引号引起来即可;
一个小坑:因为其他问题删除了node_modules
文件夹并重新cnpm install
项目依赖后,IonicPage
相关的功能报错(找不到xxx.module
),经查确定是cnpm
下载的依赖包有问题。因为墙内npm
有时不好使,最后用yarn
重新安装所有依赖解决了。
小问题:应用一开始进入A
页面,符合条件判断时自动通过getRootNav().setRoot
跳转到tabs
页面,tabs
页面用的是
组件,包含B
页面、C
页面。tab
页面、B
页面、C
页面都设置了懒加载。现在当从A
自动跳转到tabs
页面的时候,中间会有短暂的空白。不知道是tabs
还是里面的B
、C
的问题。没时间细究,就把三个页面的懒加载取消了,空白现象也确实没了。
区分开发环境和生产环境参数
1.新增src/config
目录,目录下新增三个文件:
config.dev.ts
export const ENV = {
api: '/api'
};
config.prod.ts
export const ENV = {
api: 'http://test.com/api'
};
webpack.config.js
var path = require('path');
var useDefaultConfig = require('@ionic/app-scripts/config/webpack.config.js');
module.exports = function () {
useDefaultConfig[process.env.IONIC_ENV].resolve.alias = {
"@environment": path.resolve(__dirname + '/../../src/config/config.' + process.env.IONIC_ENV + '.ts'),
};
return useDefaultConfig;
};
2.修改package.json
和tsconfig.json
:
"config": {
"ionic_webpack": "./src/config/webpack.config.js"
}
"compilerOptions": {
"baseUrl": "./src",
"paths": {
"@environment": ["config/config.prod"]
},
...
}
3.使用:
import { ENV } from '@environment';
...
url = ENV.api
//url = '/api'
//url = 'http://test.com/api'
ionic3各打包模式
--no-build 不运行Ionic build
--prod 构建生产应用程序
--aot 为此版本执行提前编译
--minifyjs 为此版本缩小C
--minifycss 为此版本缩小CSS
--optimizejs 为此构建执行JS优化
--debug 创建Cordova调试版本
--release 创建Cordova发布版本
--device 为设备创建Cordova构建
--emulator 为模拟器创建Cordova构建
--buildConfig 使用指定的Cordova构建配置
打包apk后http通信失败问题
参考文章:https://cloud.tencent.com/developer/article/1414675
找到...\resources\android\xml
下的network_security_config.xml
改为
1.这个文件是config.xml
里引用到,最终应用到app/src/main/AndroidManifest.xml
里的,所以如果直接改app/src/main/AndroidManifest.xml
而不是改这边,打包时会被覆盖。
2.等同于在AnroidManifest.xml
中的
添加设置项:android:usesCleartextTraffic="true"
关于Gradle尚未清楚的坑...
为了清理C盘空间,我按照 https://www.jianshu.com/p/5aafbd011ac8 里的做法,把C盘用户目录下的.gradle
文件夹移动到了D盘,并设置了%GRADLE_USER_HOME%
环境变量,并重启(同时还有安卓sdk也移动了,设置了%ANDROID_HOME%环境变量为新路径,并在path
里添加%ANDROID_HOME%\tools\bin;%ANDROID_HOME%\tools;%ANDROID_HOME%
,重启)。结果后来cordova build
打包一直不成功,程序一直试图下载gradle
的各种工具包并失败。为了解决做过以下尝试:
1.删除node_modules
再重新安装依赖 ---build失败
2.删除platform/android
再重新添加安卓支持 ---build失败
3.学网上文章修改platform/android
下的settings.gradle
文件 ---build失败
4.放弃移动目录,把.gradle
文件夹搬回去,删除%GRADLE_USER_HOME%
环境变量,重启 ---build失败,但报错不太一样,感觉是下载被墙了
5.翻墙后再尝试build
,终于成了,万恶的GFW
虽然最初的目的没有达成,搞不好一开始翻墙就行?但已经没有力气再来了...
调用微信接口
ionic native
和cordova
有微信插件,安装和使用方法看文档就行:
https://ionicframework.com/docs/v3/native/wechat/
但是首先要在微信开放平台申请一个移动应用的APPID
,申请时需要填应用签名
和应用包名
。
应用包名
可以在config.xml
的
里的id
属性自定义。
应用签名
可以下载微信文档里提供的签名工具,安装到手机里,同时自己的apk也要安装上。接着在签名工具里输入包名,就能得到签名了。
生成应用图标和启动图
图标准备个1024×1024px
的icon.png
,启动图准备个2732×2732px
的splash.png
。
把这两张图片放到项目目录的resources
文件夹下,然后执行命令:
ionic cordova resources
就会自动生成各种分辨率的图标和启动图了。可以在相应平台的文件夹下看到。
关于命令的官方文档:
https://ionicframework.com/docs/cli/commands/cordova-resources
ionic3 cordova打包安卓,进入页面初次加载的ion-input无法focus
问题描述:
ionic3
+cordova
打包的APP,在安卓环境(真机或模拟器,API 28
,也许API 29
也有)运行。进入页面后(例如启动时进入含有input
的登录页),在没点击过其他任何元素的情况下,首先点击页面内的
,被点击的输入框无法聚焦,也不会弹出软键盘。只有当双击输入框,或者先随便点击页面内其他元素后再点击输入框,才能正常聚焦并唤起软键盘。
这似乎是个ionic3
的bug,百度没搜到案例,github上反馈此问题出现在Android 9.0(API 28)
环境下,我这边测试反馈在Android 10
里也出现此问题。折腾了好长时间,github Issue
详见:
https://github.com/ionic-team/ionic-v3/issues/1049
最好的办法当然是ionic团队正式修复此bug,但是据反映ionic4
没有此问题(未证实),故官方可能默认让你升ionic4
就好了。如果要在ionic3
里处理,上面的issues里提到两个方案:
创建新指令覆盖当前
ion-input
的方法
详见网友 StefanRein 的指令代码:
https://github.com/ionic-team/ionic-v3/issues/1049#issuecomment-523813114
以及网友 alex-steinberg 的实例:
https://github.com/ionic-team/ionic-v3/issues/1049#issuecomment-532089605隐藏
元素
详见网友 StevenH86 的说明:
https://github.com/ionic-team/ionic-v3/issues/1049#issuecomment-530352095
https://github.com/ionic-team/ionic-v3/issues/1049#issuecomment-537640638
我先用了第一种方法,部分网友反应有效,很遗憾在我这边没有作用。
然后我用了第二种方法,也有网友表示得到了救赎,于是我按他的描述设置了:
.md .input-cover {
display: none!important;
}
结果竟然也没用,心态差点要崩了,难道我是天选之子?接着我去掉了.md
试了一试,终于有用了。至于input-cover
到底起了什么作用,我也不知道,至少隐藏后暂时还没有发现负面影响,先这么用着吧。
安卓打包报错:cordova Execution failed for task ':app:processDebugManifest'.
报错详情里有:
Element uses-permission#android.permission.CAMERA at AndroidManifest.xml :18:5-90 dupl
进入AndroidManifest.xml
(/android
文件夹里的,路径在报错里也有),发现
这个标签声明了两次。项目里用到的cordova插件有一个扫二维码的,一个扫条形码的,应该是它们引起的。因为项目的调整,正好用不到后者了,于是就把条码插件remove掉,再把/platform
文件夹和/plugins
文件夹删了,重新添加android支持,再打包就好了。
扫码枪相关需求:当input获取焦点时禁止弹出软键盘
开发一个PDA带有红外线扫条码的功能,原理是模拟键盘输入,所以需要光标焦点在input内。但是直接focus的话,会唤起软键盘,但扫码时不需要软键盘,而且还占屏幕。同时需求还要求支持用户手动输入,所以也不能完全禁用软键盘。
方法很简单,当focus事件触发的时候,给input加上readonly
属性,这样软键盘就不会弹出来;然后一个短暂的定时后再去掉readonly
属性,这样光标焦点不会失去,扫码枪就可以工作了。在这种focus状态下,用户再手动点击input,软键盘也可以弹出来:
ionFocus(){
let dom = this.el.nativeElement.querySelector('#inputer .text-input');
this.renderer.setAttribute(dom, 'readonly', 'true')
setTimeout(() => {
this.renderer.removeAttribute(dom,'readonly')
}, 200)
}
上面代码的DOM操作用到的是Renderer2
和ElementRef
import { Renderer2,ElementRef } from '@angular/core';
...
constructor(
private renderer: Renderer2,
private el:ElementRef,
)
...