Dbflow:Model object: xxxx is not registered with a Database. Did you forge an annotation?

本文解决了在华为手机上使用DbFlow出现的未注册数据库异常问题。通过在proguard-rules.pro文件中添加DbFlow混淆规则成功修复了该错误。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


错误代码:



错误描述,在三星、小米手机上运行没问题,在华为手机上抛出这个异常。

网上查询没有找到原因。

官网上提示说没有在application初始化的情况会抛出这个异常,但是初始化以后还是报这个错误。

查看源码:


/**
 * @param table The table to lookup the database for.
 * @return the corresponding {@link DatabaseDefinition} for the specified model
 */
public static DatabaseDefinition getDatabaseForTable(Class<?> table) {
    DatabaseDefinition databaseDefinition = globalDatabaseHolder.getDatabaseForTable(table);
    if (databaseDefinition == null) {
        throw new InvalidDBConfiguration("Model object: " + table.getName() +
                " is not registered with a Database. " + "Did you forget an annotation?");
    }
    return databaseDefinition;
}


/**
 * Helper method used to store a database for the specified table.
 *
 * @param table              The model table
 * @param databaseDefinition The database definition
 */
public void putDatabaseForTable(Class<?> table, DatabaseDefinition databaseDefinition) {
    databaseDefinitionMap.put(table, databaseDefinition);
    databaseNameMap.put(databaseDefinition.getDatabaseName(), databaseDefinition);
    databaseClassLookupMap.put(databaseDefinition.getAssociatedDatabaseClassFile(), databaseDefinition);
}


/**
 * This is generated code. Please do not modify */
public final class DatabaseareaNew_Database extends DatabaseDefinition {
  public DatabaseareaNew_Database(DatabaseHolder holder) {
    holder.putDatabaseForTable(Njzplace.class, this);
    models.add(Njzplace.class);
    modelTableNames.put("Njzplace", Njzplace.class);
    modelAdapters.put(Njzplace.class, new Njzplace_Table(holder, this));
  }


追溯源码,并没有发现问题。


后来,突然想到


这里会不会是混淆的时候,导致的问题,因为我在debug模式中也是开启了混淆,后来发现果然是这个原因(大家可能在平时运行时没问题,但在正式签名的apk运行时会出现这个错误)。解决方法:

在 proguard-rules.pro 中添加dbflow的混淆规则

这里会不会是混淆的时候,导致的问题,因为我在debug模式中也是开启了混淆,后来发现果然是这个原因(大家可能在平时运行时没问题,但在正式签名的apk运行时会出现这个错误)。解决方法:

在 proguard-rules.pro 中添加dbflow的混淆规则


问题就此解决。
<think>好的,用户遇到了一个错误:“index.html:1152 分片上传失败: TypeError: e.length is not a function at n.fromDer (forge.min.js:1:1) at Object.getPublicKey (index.html:1030:34) at async Object.uploadChunkedFile (index.html:1059:39)”。我需要分析这个错误的原因,并给出解决方案。 首先,错误提示指出在forge.min.js的n.fromDer函数中,e.length不是一个函数。这说明在调用forge.asn1.fromDer时,传入的参数不是一个有效的DER数据。用户提到这是在分片上传过程中发生的,所以问题可能出在获取或处理公钥的步骤。 用户之前的代码中,getPublicKey函数使用fetch获取公钥,返回的是Base64字符串。然后使用atob解码为二进制数组,再通过forge.asn1.fromDer解析。但错误提示参数e的length方法不存在,说明传入的参数可能不是预期的Uint8Array或者ArrayBuffer,而是一个字符串或其他类型。 可能的原因有几个: 1. 后端返回的公钥不是正确的DER格式,或者Base64解码后的数据不正确。 2. 在Base64解码过程中,使用atob可能导致了数据损坏,特别是当Base64字符串包含非Latin1字符时,导致解码后的二进制数据不正确。 3. forge.asn1.fromDer期望的是一个包含DER数据的字节数组,但传入的是字符串或错误的数组。 用户之前的问题中已经提到过atob处理非Latin1字符的问题,所以可能这次错误也是类似的情况。需要检查Base64解码是否正确,以及解码后的数据是否符合DER格式的要求。 解决方案可能包括: - 确保后端返回的公钥是正确格式的DER文件,并且经过Base64编码时没有多余的内容。 - 使用更可靠的解码方法,比如fetch的arrayBuffer()直接获取原始数据,避免Base64转换的中间步骤。 - 检查forge.asn1.fromDer的输入是否正确,确保传入的是DER编码的字节数组。 此外,用户提到错误发生在分片上传过程中,可能在获取公钥时异步处理失败,导致后续操作使用了无效的公钥对象,从而引发错误。需要确保getPublicKey正确返回有效的公钥,避免在错误状态下继续执行上传流程。 总结来说,错误的根本原因在于forge.asn1.fromDer接收到的参数无效,可能由于Base64解码失败或原始数据不正确。需要调整获取和解码公钥的方法,确保数据格式正确。</think>该错误是由于调用 `forge.asn1.fromDer()` 时传入了错误的参数类型,导致 `e.length` 报错。具体来说,`forge.asn1.fromDer()` 期望接收一个 **包含 DER 编码的字节数组(Uint8Array)或 ArrayBuffer**,但实际传入的是字符串或其他无效类型。 --- ### 🔍 错误根源分析 #### 1. **错误堆栈解析** ``` TypeError: e.length is not a function at n.fromDer (forge.min.js:1:1) // forge.asn1.fromDer() 被调用 at Object.getPublicKey (index.html:1030:34) // 公钥解析失败 at async Object.uploadChunkedFile (index.html:1059:39) // 分片上传流程中断 ``` #### 2. **关键代码片段** ```js // 获取公钥并解析为 ASN.1 对象 const binaryString = atob(base64PublicKey); // ⚠️ 问题根源:Base64 解码错误 const binaryArray = new Uint8Array(binaryString.length); for (let i = 0; i < binaryString.length; i++) { binaryArray[i] = binaryString.charCodeAt(i); } const asn1PublicKey = forge.asn1.fromDer(binaryArray); // ⚠️ 参数类型错误 ``` 问题出在 `forge.asn1.fromDer()` 的输入参数 `binaryArray` 实际上是 `string` 而非 `Uint8Array`,或数据格式不完整。 --- ### ✅ 解决方案 #### ✅ 方法 1:使用 `arrayBuffer()` 直接获取原始 DER 数据(推荐) 如果后端返回的是原始 DER 格式的公钥(非 Base64 编码),直接使用 `response.arrayBuffer()` 获取原始数据: ```js async getPublicKey() { const response = await fetch(`${this.apiBaseUrl}/publicKey`); const publicKeyBuffer = await response.arrayBuffer(); // 直接获取 ArrayBuffer return forge.pki.publicKeyFromAsn1(forge.asn1.fromDer(publicKeyBuffer)); } ``` #### ✅ 方法 2:确保 Base64 解码正确(当后端返回 Base64) 如果后端返回的是 Base64 编码的公钥,需确保解码后为有效的 `Uint8Array`: ```js async getPublicKey() { const response = await fetch(`${this.apiBaseUrl}/publicKey`); const base64PublicKey = await response.text(); // 获取 Base64 字符串 // Base64 解码为 Uint8Array const binaryString = atob(base64PublicKey); const binaryArray = new Uint8Array(binaryString.length); for (let i = 0; i < binaryString.length; i++) { binaryArray[i] = binaryString.charCodeAt(i); } // 确保输入是 Uint8Array const asn1PublicKey = forge.asn1.fromDer(binaryArray); // ✅ 正确参数类型 return forge.pki.publicKeyFromAsn1(asn1PublicKey); } ``` #### ✅ 方法 3:验证 Base64 字符串合法性 如果 Base64 字符串包含非法字符(如换行符 `\n`、空格),会导致 `atob()` 解码失败。可在解码前清理字符串: ```js base64PublicKey = base64PublicKey.replace(/\s+/g, ''); // 移除所有空白字符 ``` --- ### 🔧 后端注意事项 确保后端返回的公钥是标准 DER 格式(或正确 Base64 编码的 DER),并避免以下问题: - 包含 PEM 头(如 `-----BEGIN PUBLIC KEY-----`)。 - Base64 编码时包含换行符或特殊字符。 - 返回的是公钥的字符串表示而非原始二进制数据。 --- ### ✅ 验证步骤 1. **检查后端响应** 使用浏览器开发者工具(Network 面板)查看 `/publicKey` 接口返回的数据: - 如果是 DER 格式:直接使用 `arrayBuffer()`。 - 如果是 Base64:确保无多余字符,且能通过 `atob()` 解码。 2. **调试 `forge.asn1.fromDer()` 输入** 在调用 `forge.asn1.fromDer()` 前打印参数类型: ```js console.log(binaryArray instanceof Uint8Array); // 应输出 true ``` 3. **使用在线工具验证 DER 数据** 将解码后的 `Uint8Array` 通过 [ASN.1 Decoder](https://lapo.it/asn1js/) 验证是否为有效 DER 格式。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值