在Android 11中,谷歌引入了两个新的api:
数据访问审核API:AppOpsManager.OnOpNotedCallback
和流程退出原因api:getHistoricalProcessExitReasons
这两个api使我们对私有数据访问和流程退出(主要是crash)的原因更加清晰明了了,哈哈。
那么这俩api,他们是干什么的呢?先简单直白的说:
OnOpNotedCallback就是在访问私密数据时,给一个回调,看我们访问私有数据的情况。
getHistoricalProcessExitReasons就更顾名思义了,获取进程退出的原因,咋崩溃的啊,anr啊还是哪个第三方又骚了?
数据访问审核API
众所周知,Android一向鼓励开发人员谨慎敏感地访问敏感数据(这句话一定要拿给产品和老板们去看)。在Android 11中,可以用新的API,从而让我们使用私有数据和受保护数据时更加透明,规范,优雅,骚气。这对于可能具有旧版代码的大型应用程序以及使用第三方库或SDK的大型应用程序可能很有用。
因为对于大型应用程序来说,私有数据的使用可能并不容易。
第一个API是一个回调,允许应用回溯由运行时权限保护的数据的使用情况,以跟踪触发使用的代码。任何应用程序都可以在AppOpsManager中设置一个回调,该回调将在每次代码段使用私有数据(例如获取位置更新)时调用。您可以创建特定的逻辑来跟踪,提取和分析数据。
说白了就是我们可以向AppOpsManager设置一个回调,实现他的接口,在每次私有数据访问的时候,我们会在这个回调里知道权限当前的情况,有还是没有,一直拒绝还是只允许一次之类的。
参见:https://developer.android.com/preview/privacy/data-access-auditing#log-access
举个例子,某个activity中,oncreate方法:
override fun onCreate(savedInstanceState: Bundle?) {
val appOpsCallback = object : AppOpsManager.OnOpNotedCallback() {
private fun logPrivateDataAccess(opCode: String, trace: String) {
Log.i(MY_APP_TAG, "Private data accessed. " +
"Operation: $opCode\nStack Trace:\n$trace")
}
override fun onNoted(syncNotedAppOp: SyncNotedAppOp) {
logPrivateDataAccess(
syncNotedAppOp.op, Throwable().stackTrace.toString())
}
override fun onSelfNoted(syncNotedAppOp: SyncNotedAppOp) {
logPrivateDataAccess(
syncNotedAppOp.op, Throwable().stackTrace.toString())
}
override fun onAsyncNoted(asyncNotedAppOp: AsyncNotedAppOp) {
logPrivateDataAccess(asyncNotedAppOp.op, asyncNotedAppOp.message)
}
}
val appOpsManager =
getSystemService(AppOpsManager::class.java) as AppOpsManager
appOpsManager.setOnOpNotedCallback(mainExecutor, appOpsCallback)
}
回调一共复写三个方法,都是干什么的呢?:
在noted同步API调用(即返回数据或等待执行操作的API调用)中针对此包的应用程序操作时调用。
在API返回之前在调用线程上调用。允许应用程序收集堆栈跟踪以找出访问来源。
op不为null。
在该程序包无法通过其他两种方式时回调时调用。
在noted应用程序后应尽快调用,但是不能保证回调延迟。由于Android中异步调用的工作方式,甚至可能在将私有数据传递到应用程序之前将其回调。
如果该应用未运行或未OnOpNotedCallback注册,则将缓存少量已记录的应用操作,然后在注册侦听器后立即将其交付。
op不为null。
当此应用noted自己时,会调用此函数,
这非常类似于onNoted(SyncNotedAppOp),不是由API provider在其他进程中所调用而引起的回调,而是由应用程序自己的进程中的行为回调的。
op不为null。
添加归因针对具有多种功能的复杂应用程序。社交应用程序可能具有“查找朋友”功能和照片标记功能。每个功能都使用敏感数据的子集,例如,“查找朋友”使用位置和联系人,而“照片”标签使用位置,联系人和相机。在Android 11中,您可以创建一个新的Context对象,该对象可以将应用程序代码的子集归因于一个或多个功能。因此,今后,每种权限的使用都将追溯到与上下文关联的功能。
说白了,就是一个tag,你定义了这个tag,访问了一个私有数据,在我们的回调中就会拿到这个tag,通过这个tag,我们就知道是哪里访问的私有数据了。
您还可以在谷歌的代码示例中看到这些API的运行情况。
https://github.com/android/permissions-samples/tree/master/DataAccessAuditingKotlin
创建归因tag
(这个tag,因为词语根深蒂固的存在了程序员的脑海中,所以不翻译为标签了,直接说tag就完事)
class SharePhotoLocationActivity : AppCompatActivity() {
lateinit var attributionContext: Context
override fun onCreate(savedInstanceState: Bundle?) {
attributionContext = createAttributionContext("sharePhotos")
}
fun getLocation() {
val locationManager = attributionContext.getSystemService(
LocationManager::class.java) as LocationManager
// Use "locationManager" to access device location information.
}
}
在回调中拿到归因tag
val appOpsCallback = object : AppOpsManager.OnOpNotedCallback() {
private fun logPrivateDataAccess(
opCode: String, attributionTag: String, trace: String) {
Log.i(MY_APP_TAG, "Private data accessed. " +
"Operation: $opCode\n " +
"Attribution Tag:$attributionTag\nStack Trace:\n$trace")
}
override fun onNoted(syncNotedAppOp: SyncNotedAppOp) {
logPrivateDataAccess(syncNotedAppOp.op,
syncNotedAppOp.attributionTag,
Throwable().stackTrace.toString())
}
override fun onSelfNoted(syncNotedAppOp: SyncNotedAppOp) {
logPrivateDataAccess(syncNotedAppOp.op,
syncNotedAppOp.attributionTag,
Throwable().stackTrace.toString())
}
override fun onAsyncNoted(asyncNotedAppOp: AsyncNotedAppOp) {
logPrivateDataAccess(asyncNotedAppOp.op,
asyncNotedAppOp.attributionTag,
asyncNotedAppOp.message)
}
}
除了帮助您识别私有数据访问权限外,Android 11还包括新的API,以帮助查明现场中那些并非总是很严重的崩溃问题。
您可能很难找到导致应用终止的原因,原因可能有多种:ANR,崩溃或用户选择强制停止应用。为了帮助诊断原因,一些开发人员正在添加自定义代码,以构建自己的分析程序以改善应用程序的运行状况。
考虑到这一点,谷歌找到了一种使您的诊断更容易的方法。
Android 11引入了新的ActivityManager API,以报告与应用程序进程终止有关的历史信息。
您的应用可以使用API检索任何可用的历史流程退出诊断信息,例如,流程终止是由于ANR,内存问题还是其他原因。
如果应用程序由于ANR而终止,则ApplicationExitInfo.getTraceInputStream() 它将在crash之前将InputStream返回到应用程序的堆栈跟踪转储。这对于较新的OS版本尤其有用,在新OS版本中,出于隐私和安全考虑,提取ANR跟踪会更加复杂。从InputStream读取后,只需记住将其关闭以避免资源泄漏。
也就是说,ApplicationExitInfo.getTraceInputStream() 有助于我们的ANR分析。
此外,您可以使用新ActivityManager.setProcessStateSummary()方法存储自定义状态信息。这是保存任意过程数据以调试导致应用程序崩溃的代码部分的有用方法。对于某些开发人员而言,了解进程终止之前应用程序的状态也很重要-例如,游戏开发人员可能想知道用户在进程终止前所处的当前游戏级别是什么-一种常见的方法是保留该进程持续存储并在下一次应用启动时阅读。请注意,输入数据的大小非常有限。可以通过该
ApplicationExitInfo.getProcessStateSummary()方法检索任何保存的过程状态信息。
Android 11 引入了 ActivityManager.getHistoricalProcessExitReasons() 方法,用于报告近期任何进程终止的原因。应用可以使用此方法收集崩溃诊断信息,例如进程终止是由于 ANR、内存问题还是其他原因所致。此外,您还可以使用新的 setProcessStateSummary() 方法存储自定义状态信息,以便日后进行分析。
getHistoricalProcessExitReasons() 方法会返回 ApplicationExitInfo 类的实例,该类包含与应用进程终止相关的信息。通过对此类的实例调用 getReason(),您可以确定应用进程终止的原因。例如,REASON_CRASH 的返回值表示应用中发生了未处理的异常。如果应用需要确保退出事件的唯一性,可以保留特定于应用的标识符,例如基于 getTimestamp() 方法的时间戳的哈希值。
https://developer.android.com/preview/features#app-process-exit-reasons
转载需要经过我同意。然后挂上我的链接才可以哦。
你们可以去问问自己集成的第三方,尤其是crash收集第三方,有没有适配Andorid11。如果没有的话,你们就可以鄙视他们了。
程序员总喜欢站在鄙视链上,有的人就是喜欢鄙视这个鄙视那个的
总以为自己很牛×,哪来的优越感呢?
感谢https://developer.android.com/preview/features#app-process-exit-reasons
感谢https://developer.android.com/preview/privacy/data-access-auditing#create-attribution-tags