MST

星途 面试题库

面试题:Kotlin动态权限请求在多模块项目中的架构设计

假设你正在一个大型的多模块Android项目中使用Kotlin进行开发,需要进行动态权限请求。请描述如何设计一个通用的、可复用的动态权限请求架构,使其能够在不同模块中灵活调用,同时保证代码的可维护性和扩展性。
27.9万 热度难度
编程语言Kotlin

知识考点

AI 面试

面试题答案

一键面试
  1. 创建权限请求基类
    • 定义一个基类,例如BasePermissionRequest,用于封装通用的权限请求逻辑。在Kotlin中可以这样定义:
    open class BasePermissionRequest(private val activity: Activity) {
        private val requestCode = 1001
        protected fun requestPermissions(permissions: Array<String>) {
            ActivityCompat.requestPermissions(activity, permissions, requestCode)
        }
        protected fun hasPermissions(permissions: Array<String>): Boolean {
            return permissions.all {
                ActivityCompat.checkSelfPermission(activity, it) == PackageManager.PERMISSION_GRANTED
            }
        }
    }
    
  2. 具体权限请求类继承基类
    • 针对不同的权限组创建具体的请求类,继承自BasePermissionRequest。例如,创建一个用于存储权限请求的类:
    class StoragePermissionRequest(activity: Activity) : BasePermissionRequest(activity) {
        private val storagePermissions = arrayOf(
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.WRITE_EXTERNAL_STORAGE
        )
        fun requestStoragePermissions() {
            if (!hasPermissions(storagePermissions)) {
                requestPermissions(storagePermissions)
            }
        }
    }
    
  3. 在Activity中处理权限结果
    • Activity中重写onRequestPermissionsResult方法来处理权限请求的结果。
    class MainActivity : AppCompatActivity() {
        private lateinit var storagePermissionRequest: StoragePermissionRequest
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
            storagePermissionRequest = StoragePermissionRequest(this)
            storagePermissionRequest.requestStoragePermissions()
        }
        override fun onRequestPermissionsResult(
            requestCode: Int,
            permissions: Array<out String>,
            grantResults: IntArray
        ) {
            super.onRequestPermissionsResult(requestCode, permissions, grantResults)
            if (requestCode == storagePermissionRequest.requestCode) {
                if (grantResults.all { it == PackageManager.PERMISSION_GRANTED }) {
                    // 权限授予成功的逻辑
                } else {
                    // 权限授予失败的逻辑
                }
            }
        }
    }
    
  4. 模块化与复用
    • 将这些权限请求类放在一个公共的模块中,例如common - permissions模块。其他模块如果需要进行权限请求,只需要依赖这个公共模块。
    • 在不同的ActivityFragment中,通过创建相应权限请求类的实例来调用权限请求方法,从而实现代码的复用。
  5. 扩展性
    • 如果需要添加新的权限请求,只需要创建一个新的继承自BasePermissionRequest的类,并在其中定义新的权限数组和请求方法。例如,添加相机权限请求:
    class CameraPermissionRequest(activity: Activity) : BasePermissionRequest(activity) {
        private val cameraPermissions = arrayOf(Manifest.permission.CAMERA)
        fun requestCameraPermissions() {
            if (!hasPermissions(cameraPermissions)) {
                requestPermissions(cameraPermissions)
            }
        }
    }
    
    • 在需要使用相机权限的模块中,依赖公共权限模块,创建CameraPermissionRequest实例并调用其方法,就可以轻松实现新权限的请求,保证了代码的扩展性。
  6. 可维护性
    • 通过将权限请求逻辑封装在基类和具体的权限请求类中,使得权限相关的代码集中管理。如果权限请求的逻辑需要修改,例如添加新的权限检查逻辑,只需要在基类或具体的权限请求类中修改,而不需要在每个使用权限请求的地方进行修改,大大提高了代码的可维护性。