Android开发中一些注意事项和遇到的问题(持续更新)
1.LiveData使用:
setValue()
调用线程:setValue() 方法只能在主线程(UI 线程)上调用。如果你在其他线程(如后台线程或工作线程)上调用它,会抛出异常。
同步性:由于 setValue() 是在主线程上执行的,因此它是同步的。这意味着它会立即更新 LiveData 的值并通知观察者。
postValue()
调用线程:postValue() 方法可以在任何线程上调用,包括主线程和其他线程。这使得它在后台线程中更新 UI 数据时特别有用。
异步性:postValue() 不是立即更新 LiveData 的值。相反,它会将值放入一个队列中,并在主线程的消息队列中排队一个消息,以便稍后在主线程上执行。
当主线程处理这个消息时,它会从队列中取出值并更新 LiveData,然后通知观察者。因此,postValue() 是异步的。
liveData没setValue过值,获取值会是null,postValue后需要在UI主线程getValue调用,防止crash.
2.regiterListener和get调用顺序。
需要先regiterListener完再调用get,不然两个调用中间消息会被漏掉。
3.App权限的使用:(首先A app需要在manifest里将权限级别设置为normal)
使用dumpsys package com.iauto.xxxx dump权限信息:
A app已经定义iauto.permission.XX的级别为normal,为何testApp B 追加<use permission>后 dump下来的权限还是如下:
requested permissions:
iauto.permission.xxxx
install permissions:
iauto.permission.xx: granted=false
原因是需要需要重新安装testApp来重新触发权限
--》
先安装A app,然后重新后安装testApp
4.BroadCast使用
registerReceiver RECEIVER_NOT_EXPORTED和 RECEIVER_EXPORTED的区别
所以当一个广播从系统广播变为普通广播后,需要追加广播权限,让接收的模块都配置为“Intent.FLAG_RECEIVER_EXPORTED”
4.1. RECEIVER_EXPORTED(已导出)
标志:Intent.FLAG_RECEIVER_EXPORTED
行为:
接收器会被标记为可被其他应用访问(相当于在 AndroidManifest.xml 中静态注册时设置 android:exported="true")。
其他应用可以通过 sendBroadcast() 发送匹配的 Intent 到此接收器。
适用于需要跨应用通信的场景(例如系统广播或自定义全局广播)。
风险:
如果接收器处理敏感操作(如权限验证、数据修改),恶意应用可能通过发送伪造广播触发接收器,导致安全漏洞。
解决方案:确保接收器有适当的权限检查(如 android:permission),或仅在必要时导出。
4.2. RECEIVER_NOT_EXPORTED(未导出)
标志:Intent.FLAG_RECEIVER_NOT_EXPORTED
行为:
接收器仅限当前应用内部使用(相当于 android:exported="false")。
只有同一应用的组件(如 Activity、Service)或具有相同用户 ID 的应用才能发送广播到此接收器。
系统广播(如 ACTION_BATTERY_CHANGED)仍可被接收,因为系统本身有权限。
适用场景:
接收器处理应用内部逻辑(如后台任务、状态更新),无需与其他应用交互。
更安全,推荐默认使用。
5.ContentProvider的cursor.close确认在每个分支都有调用,以及捕获SQLiteException异常处理。

浙公网安备 33010602011771号