Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Kotlin中类名后的方括号_Kotlin_Syntax - Fatal编程技术网

Kotlin中类名后的方括号

Kotlin中类名后的方括号,kotlin,syntax,Kotlin,Syntax,Kotlin中类名SinglePermGroupPackagesUiInfoLiveData后的方括号是什么意思 据我目前所知。如果要新建实例以初始化局部变量packagesUiInfoLiveData,则应在其后加括号,并将groupName作为构造函数参数传递。kotlin支持速记[key]语法从映射中检索值,但它应该跟在变量后面,而不是类名后面 class CategorizedAppsLiveData(groupName: String) : MediatorLiveDa

Kotlin中类名SinglePermGroupPackagesUiInfoLiveData后的方括号是什么意思

据我目前所知。如果要新建实例以初始化局部变量packagesUiInfoLiveData,则应在其后加括号,并将groupName作为构造函数参数传递。kotlin支持速记[key]语法从映射中检索值,但它应该跟在变量后面,而不是类名后面

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
/