Kotlin中类名后的方括号
Kotlin中类名SinglePermGroupPackagesUiInfoLiveData后的方括号是什么意思 据我目前所知。如果要新建实例以初始化局部变量packagesUiInfoLiveData,则应在其后加括号,并将groupName作为构造函数参数传递。kotlin支持速记[key]语法从映射中检索值,但它应该跟在变量后面,而不是类名后面Kotlin中类名后的方括号,kotlin,syntax,Kotlin,Syntax,Kotlin中类名SinglePermGroupPackagesUiInfoLiveData后的方括号是什么意思 据我目前所知。如果要新建实例以初始化局部变量packagesUiInfoLiveData,则应在其后加括号,并将groupName作为构造函数参数传递。kotlin支持速记[key]语法从映射中检索值,但它应该跟在变量后面,而不是类名后面 class CategorizedAppsLiveData(groupName: String) : MediatorLiveDa
class CategorizedAppsLiveData(groupName: String)
: MediatorLiveData<@kotlin.jvm.JvmSuppressWildcards
Map<Category, List<Pair<String, UserHandle>>>>() {
private val packagesUiInfoLiveData = SinglePermGroupPackagesUiInfoLiveData[groupName]
}
class CategorizedAppsLiveData(组名:字符串)
:MediatorLiveData(){
私有val packagesUiInfoLiveData=SinglePermGroupPackagesUiInfoLiveData[groupName]
}
AOSP中SinglePermGroupPackagesUiInfoLiveData的定义如下:
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.permissioncontroller.permission.data
import android.app.Application
import android.os.UserHandle
import com.android.permissioncontroller.PermissionControllerApplication
import com.android.permissioncontroller.permission.model.livedatatypes.AppPermGroupUiInfo
import com.android.permissioncontroller.permission.utils.Utils
/**
* LiveData for the UI info for all packages in a single permission group. Tracks which packages
* have permissions in the given group, which should be shown on the UI, and which are granted or
* not.
*
* @param app The current application
* @param permGroupName The name of the permission group this LiveData represents
*/
class SinglePermGroupPackagesUiInfoLiveData private constructor(
private val app: Application,
private val permGroupName: String
) : SmartUpdateMediatorLiveData<Map<Pair<String, UserHandle>, AppPermGroupUiInfo>>() {
private val permGroupLiveData = PermGroupLiveData[permGroupName]
private val isCustomGroup = !Utils.getPlatformPermissionGroups().contains(permGroupName)
private val permGroupPackagesLiveData = PermGroupsPackagesLiveData.get(
customGroups = isCustomGroup)
/**
* Map<Pair<package name, UserHandle>, UI data LiveData>
*/
private val appPermGroupLiveDatas = mutableMapOf<Pair<String, UserHandle>,
AppPermGroupUiInfoLiveData>()
/**
* Map<Pair<packageName, userHandle>, UI data>.
*/
private val shownPackages = mutableMapOf<Pair<String, UserHandle>, AppPermGroupUiInfo>()
init {
addSource(permGroupLiveData) { newPermGroup ->
if (newPermGroup == null) {
invalidateSingle(permGroupName)
value = null
}
}
addSource(permGroupPackagesLiveData) {
updateIfActive()
}
}
override fun onUpdate() {
val thisPermGroupPackages = permGroupPackagesLiveData.value?.get(permGroupName)
if (thisPermGroupPackages != null) {
addAndRemoveAppPermGroupLiveDatas(thisPermGroupPackages.toList())
if (thisPermGroupPackages.isEmpty()) {
permGroupLiveData.value?.groupInfo?.let {
value = emptyMap()
}
}
}
}
private fun addAndRemoveAppPermGroupLiveDatas(pkgs: List<Pair<String, UserHandle>>) {
val getLiveData = { key: Pair<String, UserHandle> ->
AppPermGroupUiInfoLiveData[key.first, permGroupName, key.second]
}
setSourcesToDifference(pkgs, appPermGroupLiveDatas, getLiveData) { key ->
val appPermGroupUiInfoLiveData = appPermGroupLiveDatas[key]
val appPermGroupUiInfo = appPermGroupUiInfoLiveData?.value
shownPackages.remove(key)
if (appPermGroupUiInfo == null) {
if (appPermGroupUiInfoLiveData != null &&
appPermGroupUiInfoLiveData.isInitialized) {
removeSource(appPermGroupUiInfoLiveData)
appPermGroupLiveDatas.remove(key)
}
} else {
shownPackages[key] = appPermGroupUiInfo
}
if (appPermGroupLiveDatas.all { entry -> entry.value.isInitialized }) {
permGroupLiveData.value?.groupInfo?.let {
value = shownPackages.toMap()
}
}
}
}
/**
* Repository for SinglePermGroupPackagesUiInfoLiveData objects.
* <p> Key value is a string permission group name, value is its corresponding LiveData.
*/
companion object : DataRepository<String,
SinglePermGroupPackagesUiInfoLiveData>() {
override fun newValue(key: String): SinglePermGroupPackagesUiInfoLiveData {
return SinglePermGroupPackagesUiInfoLiveData(PermissionControllerApplication.get(),
key)
}
}
}
/*
*版权所有(C)2019安卓开源项目
*
*根据Apache许可证2.0版(以下简称“许可证”)获得许可;
*除非遵守许可证,否则不得使用此文件。
*您可以通过以下方式获得许可证副本:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*除非适用法律要求或书面同意,软件
*根据许可证进行的分发是按“原样”进行分发的,
*无任何明示或暗示的保证或条件。
*请参阅许可证以了解管理权限和权限的特定语言
*许可证下的限制。
*/
包com.android.permissioncontroller.permission.data
导入android.app.Application
导入android.os.UserHandle
导入com.android.permissioncontroller.PermissionControllerApplication
导入com.android.permissioncontroller.permission.model.livedatatypes.AppPermGroupUiInfo
导入com.android.permissioncontroller.permission.utils.utils
/**
*单个权限组中所有包的UI信息的LiveData。跟踪哪些包
*在给定的组中拥有权限,这些权限应显示在UI上,并且被授予或删除
*不是。
*
*@param app当前应用程序
*@param permGroupName此LiveData表示的权限组的名称
*/
类SinglePermGroupPackagesUiInfoLiveData专用构造函数(
私有val应用程序:应用程序,
private val permGroupName:字符串
):SmartUpdateMediatorLiveData(){
private val permGroupLiveData=permGroupLiveData[permGroupName]
private val isCustomGroup=!Utils.getPlatformPermissionGroups().contains(permGroupName)
private val permGroupPackagesLiveData=PermGroupsPackagesLiveData.get(
customGroups=isCustomGroup)
/**
*地图
*/
private val appPermGroupLiveDatas=mutableMapOf()
/**
*地图。
*/
private val shownPackages=mutableMapOf()
初始化{
addSource(permGroupLiveData){newPermGroup->
if(newPermGroup==null){
invalidateSingle(permGroupName)
值=空
}
}
addSource(permGroupPackagesLiveData){
updatefactive()
}
}
重写操作更新(){
val thisPermGroupPackages=permGroupPackagesLiveData.value?.get(permGroupName)
if(thisPermGroupPackages!=null){
addAndRemoveAppPermGroupLiveDatas(thisPermGroupPackages.toList())
if(thisPermGroupPackages.isEmpty()){
permGroupLiveData.value?.groupInfo?.let{
value=emptyMap()
}
}
}
}
private fun addAndRemoveAppPermGroupLiveDatas(打包:列表){
val getLiveData={key:Pair->
AppPermGroupUiInfoLiveData[key.first、permGroupName、key.second]
}
setSourcesToDifference(pkgs、appPermGroupLiveDatas、getLiveData){key->
val appPermGroupUiInfoLiveData=appPermGroupLiveDatas[键]
val appPermGroupUiInfo=appPermGroupUiInfoLiveData?.value
显示包。删除(键)
如果(appPermGroupUiInfo==null){
if(appPermGroupUiInfoLiveData!=null&&
appPermGroupUiInfoLiveData.i初始化){
removeSource(appPermGroupUiInfoLiveData)
appPermGroupLiveDatas.remove(键)
}
}否则{
shownPackages[key]=appPermGroupUiInfo
}
if(appPermGroupLiveDatas.all{entry->entry.value.isInitialized}){
permGroupLiveData.value?.groupInfo?.let{
value=shownPackages.toMap()
}
}
}
}
/**
*SinglePermGroupPackagesUiInfoLiveData对象的存储库。
*Key value是字符串权限组名称,value是其对应的LiveData。
*/
伴生对象:DataRepository(){
重写新值(键:字符串):SinglePermGroupPackagesUiInfoLiveData{
返回SinglePermGroupPackagesUiInfoLiveData(PermissionControllerApplication.get(),
钥匙)
}
}
}
/*********************更新****************************/
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.permissioncontroller.permission.data
import android.app.ActivityManager
import android.content.ComponentCallbacks2
import android.content.res.Configuration
import androidx.annotation.GuardedBy
import androidx.annotation.MainThread
import com.android.permissioncontroller.PermissionControllerApplication
import java.util.concurrent.TimeUnit
/**
* A generalize data repository, which carries a component callback which trims its data in response
* to memory pressure
*/
abstract class DataRepository<K, V : DataRepository.InactiveTimekeeper> : ComponentCallbacks2 {
/**
* Deadlines for removal based on memory pressure. Live Data objects which have been inactive
* for longer than the deadline will be removed.
*/
private val TIME_THRESHOLD_LAX_NANOS: Long = TimeUnit.NANOSECONDS.convert(5, TimeUnit.MINUTES)
private val TIME_THRESHOLD_TIGHT_NANOS: Long = TimeUnit.NANOSECONDS.convert(1, TimeUnit.MINUTES)
private val TIME_THRESHOLD_ALL_NANOS: Long = 0
protected val lock = Any()
@GuardedBy("lock")
protected val data = mutableMapOf<K, V>()
/**
* Whether or not this data repository has been registered as a component callback yet
*/
private var registered = false
/**
* Whether or not this device is a low-RAM device.
*/
private var isLowMemoryDevice = PermissionControllerApplication.get().getSystemService(
ActivityManager::class.java)?.isLowRamDevice ?: false
init {
PermissionControllerApplication.get().registerComponentCallbacks(this)
}
/**
* Get a value from this repository, creating it if needed
*
* @param key The key associated with the desired Value
*
* @return The cached or newly created Value for the given Key
*/
operator fun get(key: K): V {
synchronized(lock) {
return data.getOrPut(key) { newValue(key) }
}
}
/**
* Generate a new value type from the given data
*
* @param key Information about this value object, used to instantiate it
*
* @return The generated Value
*/
@MainThread
protected abstract fun newValue(key: K): V
/**
* Remove LiveData objects with no observer based on the severity of the memory pressure. If
* this is a low RAM device, eject all caches always, including upon the UI closing.
*
* @param level The severity of the current memory pressure
*/
override fun onTrimMemory(level: Int) {
if (isLowMemoryDevice) {
trimInactiveData(TIME_THRESHOLD_ALL_NANOS)
return
}
trimInactiveData(threshold = when (level) {
ComponentCallbacks2.TRIM_MEMORY_BACKGROUND -> TIME_THRESHOLD_LAX_NANOS
ComponentCallbacks2.TRIM_MEMORY_MODERATE -> TIME_THRESHOLD_TIGHT_NANOS
ComponentCallbacks2.TRIM_MEMORY_COMPLETE -> TIME_THRESHOLD_ALL_NANOS
ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE -> TIME_THRESHOLD_LAX_NANOS
ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW -> TIME_THRESHOLD_TIGHT_NANOS
ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL -> TIME_THRESHOLD_ALL_NANOS
else -> return
})
}
override fun onLowMemory() {
onTrimMemory(ComponentCallbacks2.TRIM_MEMORY_COMPLETE)
}
override fun onConfigurationChanged(newConfig: Configuration) {
// Do nothing, but required to override by interface
}
fun invalidateSingle(key: K) {
synchronized(lock) {
data.remove(key)
}
}
private fun trimInactiveData(threshold: Long) {
synchronized(lock) {
data.keys.toList().forEach { key ->
if (data[key]?.timeInactive?.let { it >= threshold } == true) {
data.remove(key)
}
}
}
}
/**
* Interface which describes an object which can track how long it has been inactive, and if
* it has any observers.
*/
interface InactiveTimekeeper {
/**
* Long value representing the time this object went inactive, which is read only on the
* main thread, so does not cause race conditions.
*/
var timeWentInactive: Long?
/**
* Calculates the time since this object went inactive.
*
* @return The time since this object went inactive, or null if it is not inactive
*/
val timeInactive: Long?
get() {
val time = timeWentInactive ?: return null
return System.nanoTime() - time
}
}
}
/**
* A DataRepository where all values are contingent on the existence of a package. Supports
* invalidating all values tied to a package. Expects key to be a pair or triple, with the package
* name as the first value of the key.
*/
abstract class DataRepositoryForPackage<K, V : DataRepository.InactiveTimekeeper>
: DataRepository<K, V>() {
/**
* Invalidates every value with the packageName in the key.
*
* @param packageName The package to be invalidated
*/
fun invalidateAllForPackage(packageName: String) {
synchronized(lock) {
for (key in data.keys.toSet()) {
if (key is Pair<*, *> || key is Triple<*, *, *> && key.first == packageName) {
data.remove(key)
}
}
}
}
}
/**
* A convenience to retrieve data from a repository with a composite key
*/
operator fun <K1, K2, V : DataRepository.InactiveTimekeeper> DataRepository<Pair<K1, K2>, V>.get(
k1: K1,
k2: K2
): V {
return get(k1 to k2)
}
/**
* A convenience to retrieve data from a repository with a composite key
*/
operator fun <K1, K2, K3, V : DataRepository.InactiveTimekeeper>
DataRepository<Triple<K1, K2, K3>, V>.get(
k1: K1,
k2: K2,
k3: K3
): V {
return get(Triple(k1, k2, k3))
}
/*
*版权所有(C)2019安卓开源项目
*
*根据Apache许可证2.0版(以下简称“许可证”)获得许可;
*除非遵守许可证,否则不得使用此文件。
*您可以通过以下方式获得许可证副本:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*除非适用法律要求或书面同意,软件
*根据许可证进行的分发是按“原样”进行分发的,
*无任何明示或暗示的保证或条件。
*请参阅许可证以了解管理权限和权限的特定语言
*许可证下的限制。
*/
包com.android.permissioncontroller.permission.data
导入android.app.ActivityManager
导入android.content.ComponentCallbacks2
导入android.content.res.Configuration
导入androidx.annotation.GuardedBy
导入androidx.annotation.MainThread
导入com.android.permissioncontroller.PermissionControllerApplication
导入java.util.concurrent.TimeUnit
/