最近在使用 uni-app 开发 Android 应用,过程中涉及自定义基座、原生插件接入、微信登录、流式传输等内容。这里把踩过的坑和关键配置整理一下,方便后续回顾。
自定义基座
下载源码
先到 DCloud 官方文档下载自定义基座的基础代码:Android 离线 SDK 文档。
下载后主要使用其中的 HBuilder-Integrate-AS 文件包。
增加自定义配置
1. 配置 Gradle 依赖
在 ~\HBuilder-Integrate-AS\simpleDemo\build.gradle 中增加或确认以下依赖:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| dependencies { implementation fileTree(dir: 'libs', include: ['*.aar', '*.jar'], exclude: []) implementation 'androidx.appcompat:appcompat:1.1.0' implementation 'androidx.localbroadcastmanager:localbroadcastmanager:1.0.0' implementation 'androidx.core:core:1.1.0' implementation "androidx.fragment:fragment:1.1.0" implementation 'androidx.recyclerview:recyclerview:1.1.0' implementation 'com.facebook.fresco:fresco:2.5.0' implementation "com.facebook.fresco:animated-gif:2.5.0" implementation 'com.github.bumptech.glide:glide:4.9.0' implementation 'androidx.webkit:webkit:1.5.0' implementation 'com.tencent.mm.opensdk:wechat-sdk-android:+'
implementation "com.alibaba:fastjson:1.2.83" implementation "com.squareup.okhttp3:okhttp:3.12.12" implementation("net.lingala.zip4j:zip4j:2.11.5") implementation 'com.squareup.okio:okio:1.15.0'
debugImplementation fileTree(includes: ['.jar', '.aar'], dir: 'debug/libs') }
|
2. 配置 DCloud AppKey
在 AndroidManifest.xml 的 application 节点中增加 DCloud 的 appkey:
1 2 3
| <meta-data android:name="dcloud_appkey" android:value="填写你的appkey" />
|
这里的 appkey 需要到 DCloud 后台申请,并且要和 Android 证书信息匹配。
3. 可选:接入微信能力
如果项目需要使用微信登录、分享等能力,需要在同一个位置继续增加微信相关配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <meta-data android:value="填写你的APPID" android:name="WX_APPID" />
<activity android:name="这里填写WXEntryActivity在项目中的路径" android:label="@string/app_name" android:exported="true" android:launchMode="singleTop" android:theme="@android:style/Theme.Translucent.NoTitleBar"> <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <data android:scheme="填写你的APPID" /> </intent-filter> </activity>
|
我是在 src/main/java/cn.com.wxapi 目录下创建的 WXEntryActivity 文件,内容如下:
1 2 3 4 5 6 7 8 9 10 11
| package cn.com.wxapi;
import io.dcloud.feature.oauth.weixin.AbsWXCallbackActivity;
public class WXEntryActivity extends AbsWXCallbackActivity {
}
|
4. 导入 data 文件
将 SDK 中的 SDK/assets/data/ 目录导入到项目的 main/assets/data/ 中。
导入后需要修改 dcloud_control.xml 中的 appid,确保它和当前 uni-app 项目保持一致。
运行 Android 项目
运行 Android 项目时,需要先用 HBuilderX 生成 App 资源,然后把生成后的代码放到原生项目的 main/assets/apps/ 目录中。
开发中遇到的问题
流式传输
uni-app 在 Android 端处理流式响应时,直接使用普通请求并不方便。我的处理方式是通过 renderjs 配合 fetch-event-source 实现 SSE 流式传输。
示例代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
| h5PostStream(url, data) { let controller = null; let onChunkCallback = null; let onErrorCallback = null; let onCompleteCallback = null;
const streamTask = { onChunkReceived(callback) { onChunkCallback = callback; },
onError(callback) { onErrorCallback = callback; },
onComplete(callback) { onCompleteCallback = callback; },
abort() { if (controller) { controller.abort(); } }, };
setTimeout(() => { controller = new AbortController();
fetchEventSource(baseurl + url, { method: 'POST', headers: { 'Content-Type': 'application/json', Authorization: getToken(), Accept: 'text/event-stream', }, body: JSON.stringify(data), signal: controller.signal,
onopen(response) { if (response.ok) { console.log('SSE 连接已建立'); return; }
if (response.status === 401 || response.status === 403) { throw new Error('认证失败'); }
throw new Error('连接失败: ' + response.status); },
onmessage(event) { if (onChunkCallback && event.data) { const encoder = new TextEncoder(); const arrayBuffer = encoder.encode(event.data).buffer;
onChunkCallback({ data: arrayBuffer, }); } },
onerror(err) { console.error('SSE 错误:', err);
if (err.message && err.message.includes('认证失败')) { useDialog('登录过期,请前往登录', { title: '提示', showCancelButton: true }) .then(() => { uni.navigateTo({ url: '/pages/login/phone/index', }); }) .catch(err => {}); }
if (onErrorCallback) { onErrorCallback(err); }
throw err; },
onclose() { console.log('SSE 连接已关闭'); if (onCompleteCallback) { onCompleteCallback(); } },
openWhenHidden: false, }); }, 0);
return streamTask; },
|
ECharts 的写法差异
Android 端使用 ECharts 时,不需要像小程序一样额外注册 canvas。
我的做法是直接全量导入 echarts,然后按正常方式初始化和注册图表即可。
本地安装原生插件
这里以阿里云一键登录插件为例。
1. 放置插件文件
先到 阿里云号码认证插件 下载插件。
打开 Android 本地框架后,将插件的 aar 文件放到项目的 libs 目录下。
然后在 assets 目录中创建 dcloud_uniplugins.json,内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13
| { "nativePlugins": [ { "plugins": [ { "type": "module", "name": "AliCloud-NirvanaPns", "class": "com.nirvana.prd.auth.ALiLoginManager" } ] } ] }
|
dcloud_uniplugins.json 中的这些信息,可以在离线安装包内的 package.json 中找到。
2. 增加依赖配置
build.gradle 中还需要加入插件依赖,具体可参考上面的「配置 Gradle 依赖」章节。
3. 注意回调函数写法
阿里云一键登录的回调函数不要使用 async。
如果回调函数使用了 async,授权页可能会被阻塞,表现为没有报错,但授权页也不会弹出。
接入微信登录
微信登录可以直接使用 uni-app 的 uni.login API,并将登录方式设置为微信登录。
需要注意的是,微信登录不能只依赖自定义基座调试验证,最好打正式包后再测试。
另外,打包时使用的证书和签名必须与微信开放平台配置保持一致,否则微信登录无法正常拉起。