准备工作
- 到 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 28buildToolsVersion '28.0.3'defaultConfig {applicationId "com.lizhiboxue.test"minSdkVersion 23targetSdkVersion 28versionCode 100versionName "1.0.0"multiDexEnabled truendk {abiFilters 'x86','armeabi-v7a'}}buildTypes {release {minifyEnabled falseproguardFiles 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"><applicationandroid:allowBackup="true"android:allowClearUserData="true"android:icon="@drawable/icon"android:label="@string/app_name"android:largeHeap="true"android:supportsRtl="true"><activityandroid: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><activityandroid: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:
<activityandroid:name="io.dcloud.PandoraEntry"android:label="@string/app_name">...
修改包名及应用版本
修改 app/build.gradle 中的 applicationId 字段:
android {compileSdkVersion 26buildToolsVersion '28.0.3'defaultConfig {applicationId "com.example.test.Hello"minSdkVersion 19targetSdkVersion 26versionCode 100versionName "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>,比如
<providerandroid:name="io.dcloud.common.util.DCloud_FileProvider"android:authorities="${applicationId}.fileprovider"</provider>
可以使用替换:
from: android:authorities="io.dcloud.HelloH5to: 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 进行安装。
