Android 开发问题备忘

  • 写 android 时遇到的奇葩问题

  • 资料来源:

    <>

  • 更新

    1
    2022.06.26 初始

导语

这是一个集合备忘贴,汇总一些难忘的开发问题.

Room 数据库 Error: Cannot provide null context for the database

nowakelock 尝试 hook 系统 com.android.providers.settings 把数据库建立在系统进程,这样 nowakelock 不再需要保存后台.

初始化 room 数据库时一直遇到 Error: Cannot provide null context for the database.

传入的 context 是 ContentProvider::getContext 已经在 deepsleep 试验过了,应该是没啥问题的,就这样卡了很久…

详细查询后关联问题 -> Android JUnit test with Context.getApplicationContext()

context.applicationContext -> context

1
2
3
4
Room.databaseBuilder(
context.applicationContext, InfoDatabase::class.java,
DATABASE_NAME
).build()
1
2
3
4
Room.databaseBuilder(
context, InfoDatabase::class.java,
DATABASE_NAME
).build()

fragment toolbar 菜单栏时常失效

fragment 中设置 toolbar 的菜单.通常是覆盖 onCreateOptionsMenu 再到 onCreat 添加一句 setHasOptionsMenu(true).

一直有 'setHasOptionsMenu(Boolean): Unit' is deprecated. Deprecated in Java 的提示,基本没去管它3,直到最近菜单栏一直失效…

关联问题 -> ‘setHasOptionsMenu(Boolean): Unit’ is deprecated. Deprecated in Java

实际上 androidX 提供了替代方式 MenuProvider -> Version 1.4.0-alpha01

Room

room 好用但是坑实在不少…

Relation 不支持复合主键

定义 一对一 关系时,常用 @Relation 以完成不同表的 1:1 映射.但 @Relation 不支持复合主键… 对应 issues -> Relation don’t support Composite Primary Key

  • 已经放了 5 年了…
  • 好在 Room 最近支持了 多重映射返回值类型,也就是说可以返回 map 类型,再通过 flow 组合成想要的复合类型.

还有个比较奇葩的需求: 1:1 时左边不为空,但右边可能为空.

  • sqlite 的左外联,然后 DAO 方法返回声明可为空.

自动迁移失败

Room 在 2.4.0-alpha01 支持了自动迁移,但是不巧,当遇到表/列重命名时,还是不行.

androidx.room.AutoMigration 声明时加入 AutoMigrationSpec 静态类.官方示例给的是直接在 数据库类内实现.

1
2
3
4
5
6
7
8
@RenameColumn(
tableName = "info",
fromColumnName = "userId",
toColumnName = "userid_info"
)
class MyAutoMigration : AutoMigrationSpec

androidx.room.AutoMigration(from = 4, to = 5, spec = AppDatabase.MyAutoMigration::class)

Android Gradle plugin requires Java 11 to run. You are currently using Java 1.8

目前(23.5.10) 升级 deepsleep 时遇到这个错误,似乎是本地 jdk 版本太低了.

参考 > https://stackoverflow.com/questions/66980512/android-studio-error-android-gradle-plugin-requires-java-11-to-run-you-are-cur

Preferences → Build, Execution, Deployment → Build Tools → Gradle → Gradle JDK

  • 此时的版本是 1.8 , 需要选择任何一个大于等于 11 的 jdk 版本
  • 从我这看,基本都 java 17 了…

然后重新编译, 不行再重启 AS 清理缓存.