准备工作
- 到 Android 离线SDK - 正式版 下载最新的SDK
- 解压后看到以下目录结构:
- 将 HBuilder-Hello 项目复制一份放到其他地方,使用Android Studio打开
创建工程
首先创建一个空的Android工程:
File | New | New Project…
选择Empty Activity
为自己的工程取个名字,并配置包名、工程路径等,点击Finish。创建好的工程结构:
修改 app/build.gradle
apply plugin: 'com.android.application'
android {
compileSdkVersion 28
buildToolsVersion '28.0.3'
defaultConfig {
applicationId "com.lizhiboxue.test"
minSdkVersion 23
targetSdkVersion 28
versionCode 100
versionName "1.0.0"
multiDexEnabled true
ndk {
abiFilters 'x86','armeabi-v7a'
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
//使用uniapp时,需复制下面代码
/*代码开始*/
aaptOptions {
additionalParameters '--auto-add-overlay'
//noCompress 'foo', 'bar'
ignoreAssetsPattern "!.svn:!.git:.*:!CVS:!thumbs.db:!picasa.ini:!*.scc:*~"
}
/*代码结束*/
}
repositories {
flatDir {
dirs 'libs'
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.aar', '*.jar'], exclude: [])
implementation "com.android.support:support-v4:28.0.0"
implementation "com.android.support:appcompat-v7:28.0.0"
/*uniapp所需库-----------------------开始*/
implementation 'com.android.support:recyclerview-v7:28.0.0'
implementation 'com.facebook.fresco:fresco:1.13.0'
implementation "com.facebook.fresco:animated-gif:1.13.0"
/*uniapp所需库-----------------------结束*/
// 基座需要,必须添加
implementation 'com.github.bumptech.glide:glide:4.9.0'
implementation 'com.alibaba:fastjson:1.1.46.android'
}
包含以下改动:
- 将其 targetSdkVersion 配置为28以下(为了适配Android Q,详见适配Android10 / Android Q(API 29))
- 将其 targetSdkVersion 配置为21以上,建议此属性值设为23,
`io.dcloud.PandoraEntry
作为apk入口时 必须设置targetSDKVersion>=21
沉浸式才生效 - minSdkVersion必须是19以上,uniapp才起作用
- 添加
ndk.abiFilters
,以支持指定的架构 - 添加
aaptOptions
节点 - 修改
dependencies
引入依赖
首先导入HBuilder-Integrate-AS
项目中的simpleDemo
模块
可以看到以下结构:
然后将simpleDemo
模块中的libs
复制到app
模块中
引入资源
先将我们自己创建的项目中的src删掉,再将simpleDemo
中的src复制覆盖到app模块中,可以看到以下目录结构:
启动图及APP名称
位于 res
下的目录结构:
在drawable
下:
icon.png
为应用的图标。push.png
为推送消息的图标。splash.png
为应用启动页的图标。
在values/string.xml
中,里面配置了应用的名称:
<resources>
<string name="app_name">uniapp-android</string>
</resources>
应用配置
在assets
中,apps下存放了所有的应用,以 应用名/www
的目录结构存放。
可以看出,www
目录存放的都是一些编译后的网页资源(没有编译也行,资源是由manifest.json指定)
其中 data
目录中的 dcloud_control.xml
可以指定特定的应用:
<hbuilder>
<apps>
<app appid="HelloH5" appver=""/>
</apps>
</hbuilder>
AndroidManifest.xml
AndroidManifest.xml
为应用程序清单,需要将启动页面指定为io.dcloud.PandoraEntry
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="io.dcloud.simple">
<application
android:allowBackup="true"
android:allowClearUserData="true"
android:icon="@drawable/icon"
android:label="@string/app_name"
android:largeHeap="true"
android:supportsRtl="true">
<activity
android:name="io.dcloud.PandoraEntry"
android:configChanges="orientation|keyboardHidden|keyboard|navigation"
android:label="@string/app_name"
android:launchMode="singleTask"
android:hardwareAccelerated="true"
android:theme="@style/TranslucentTheme"
android:screenOrientation="user"
android:windowSoftInputMode="adjustResize" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="io.dcloud.PandoraEntryActivity"
android:launchMode="singleTask"
android:configChanges="orientation|keyboardHidden|screenSize|mcc|mnc|fontScale|keyboard"
android:hardwareAccelerated="true"
android:permission="com.miui.securitycenter.permission.AppPermissionsEditor"
android:screenOrientation="user"
android:theme="@style/DCloudTheme"
android:windowSoftInputMode="adjustResize">
<intent-filter>
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<action android:name="android.intent.action.VIEW" />
<data android:scheme="h56131bcf" />
</intent-filter>
</activity>
</application>
</manifest>
之后集成各种资源的时候,还需要在 AndroidManifest.xml
中进行权限配置等操作。
启动程序
一切配置完毕,直接运行即可
打包uniapp资源
首先,需要将本地cli项目升级到跟最新版SDK相同的版本:
yarn upgrade
打包本地项目,默认可以使用以下命令:
yarn build:app-plus
实际上是调用了:
cross-env NODE_ENV=production UNI_PLATFORM=app-plus vue-cli-service uni-build
如果需要指定资源生成路径,可以手动指定 UNI_OUTPUT_DIR
cross-env NODE_ENV=production UNI_PLATFORM=app-plus UNI_OUTPUT_DIR=./platforms/android/app/src/main/assets/apps/<appid>/www vue-cli-service uni-build
打包好的资源长这样:
记住 mainfest.json
中的 appid,在Android原生工程的 assets/apps
中创建相同appid名称的目录,并创建一个www目录,结构如下:
将打包好的资源全部拷到 <appid>/www
目录下:
修改data/dcloud_control.xml文件中的appid为项目的appid:
如果不嫌麻烦,也可以通过HBuilderX打包资源(不推荐):
应用设置
修改应用名
修改 res/values/strings.xml
的 app_name 字段为应用名称,比如:
<resources>
<string name="app_name">UniappTest</string>
</resources>
注意查看 AndroidManifest.xml
中 activity 的 android:label
属性值是否为 @string/app_name
:
<activity
android:name="io.dcloud.PandoraEntry"
android:label="@string/app_name"
>
...
修改包名及应用版本
修改 app/build.gradle
中的 applicationId
字段:
android {
compileSdkVersion 26
buildToolsVersion '28.0.3'
defaultConfig {
applicationId "com.example.test.Hello"
minSdkVersion 19
targetSdkVersion 26
versionCode 100
versionName "0.0.1"
}
...
修改 AndroidManifest.xml
文件中的 package 属性值为应用包名,versionCode versionName 为版本, 比如:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.example.test.Hello"
android:versionCode="100"
android:versionName="0.0.1"
>
...
修改 AndroidManifest.xml
中的 provider 节点下的 android:authorities
属性值为 ${applicationId}.<xxx>
,比如
<provider
android:name="io.dcloud.common.util.DCloud_FileProvider"
android:authorities="${applicationId}.fileprovider"
</provider>
可以使用替换:
from: android:authorities="io.dcloud.HelloH5
to: android:authorities="${applicationId}
参考:INSTALL FAILED CONFLICTING PROVIDER问题完美解决方案
修改闪屏页图片和图标
将 res/drawable-xxhdpi
下的 icon.png
push.png
splash.png
三个文件进行替换即可。
签名打包
- 选择
Build->Generate Signed Bundle/APK...
- 选择APK
- 如果没有证书,选择“创建证书”,如果已经有了证书,则可以选择已有证书
- 选择证书后,选择打包类型为release或debug,Signature Versions建议都选,点击Finish
- 打包成功后的apk:
默认apk生成路径为 app/release
,如果是debug版本为 app/debug
关于自定义基座
在调试的时候,我们通产会使用自定义基座进行调试,如果使用默认基座,在调试多个应用的时候会出现应用相互覆盖的情况。
自定义基座可以使用上面打包好的APK,将其复制到 dist\debug\android_debug.apk
即可:
实际上,自定义基座的作用是为了区分不同包名的应用,因为默认基座的包名是确定的:io.dcloud.HBuilder
, 因此才会出现相互覆盖的情况。
说到这,其实使用HBuilderX在线打包的话,有一个非常不错的地方:可以任意修改包名。而离线打包可能改包名就比较麻烦了。
安装apk时的错误处理
我在安装打包好的apk时,出现了以下错误:
错误:more than one device/emulator
错误原因:有多个真机/模拟器连接到电脑。
解决方案:断开多余的真机/ 模拟器,只留一个。
错误:INSTALL_FAILED_UPDATE_INCOMPATIBLE
错误原因:模拟器中包含一个相同的应用,但签名不同。一般是由于之前安装过测试版本的apk,导致安装正式版本的apk时签名不一致。
解决方案:卸载掉之前安装的测试版本。
错误:INSTALL_FAILED_DUPLICATE_PERMISSION
错误原因:已经有其他app申请过这个权限,导致权限重复。一般是由于之前安装过默认项目中的 HBuilder-Hello。
解决方案:卸载掉HBuilder-Hello。
错误:INSTALL_FAILED_ALREADY_EXISTS
错误原因:签名后再次安装会出错。
解决方案:使用 adb install -r xxx.apk
进行安装。