Jetpack来了,利用LiveData “换掉” RxPermission

栏目: IT技术 · 发布时间: 5年前

内容简介:本文作者链接:

本文作者

作者: 反魂蝶五分

链接:

https://blog.csdn.net/u014290233/article/details/104383929

本文由作者授权发布。

1

概述

在以前,我们项目框架通常使用Rxjava+Retrofit+okhttp,所以使用RxPermissions进行动态权限申请就顺理成章了。随着Google新技术的推出,kotlin、jetpack成为大势所趋,如果项目中没有使用Rxjava,那么依赖于Rxjava的RxPermissions也就无法适用了。

RxPermissions 利用了Rxjava的观察者模式,而jetpack也提供了一种可观察的数据存储器类——LiveData,所以可以利用LiveData完成类似RxPermissions的动态权限申请框架,而且LiveData能够感知组件的生命周期,当 Activity 和 Fragment 的生命周期被销毁时,系统会立即退订它们,避免内存泄漏。

如果观察者(由 Observer 类表示)的生命周期处于 STARTED 或 RESUMED 状态,则 LiveData 会认为该观察者处于活跃状态。LiveData 只会将更新通知给活跃的观察者。为观察 LiveData 对象而注册的非活跃观察者不会收到更改通知。

2

代码实现

我们需要新建一个Fragment,用这个Fragment来进行权限的申请处理(新建Fragment的用途很广泛,比如Glide就是通过创建一个Fragment,然后通过这个Fragment感知生命周期),需要注意的是如果当前在Fragment里申请权限,需要用fragment.childFragmentManager,

class LivePermissions {
    ......

    constructor(activity: AppCompatActivity) {
        liveFragment = getInstance(activity.supportFragmentManager)
    }

    constructor(fragment: Fragment) {
        liveFragment = getInstance(fragment.childFragmentManager)
    }

    @Volatile
    private var liveFragment: LiveFragment? = null

    private fun getInstance(fragmentManager: FragmentManager) =
        liveFragment ?: synchronized(this) {
            liveFragment ?: if (fragmentManager.findFragmentByTag(TAG) == null) LiveFragment().run {
                fragmentManager.beginTransaction().add(this, TAG).commitNow()
                this
            } else fragmentManager.findFragmentByTag(TAG) as LiveFragment
        }
    ......
}

权限申请方法,在这里调用Fragment的申请申请方法并返回MutableLiveData,MutableLiveData是LiveData的子类,使用setValue或者postValue传入数据,通过LiveData.observe(LifecycleOwner,Observer)传入观察者观察数据更新,这样在Fragment里通过MutableLiveData将权限申请的结果回调回去。

    fun request(vararg permissions: String): MutableLiveData<PermissionResult> {
        return this.requestArray(permissions)
    }

    fun requestArray(permissions: Array<out String>): MutableLiveData<PermissionResult> {
        liveFragment!!.requestPermissions(permissions)
        return liveFragment!!.liveData
    }

    ......
}

创建LiveFragment继承Fragment。在requestPermissions方法里创建MutableLiveData并调用Android申请权限的方法,这里在onRequestPermissionsResult里处理返回结果。

返回结果这里创建了2个ArrayList,分别用来临时保持“拒绝”和“拒绝并不再询问”的权限,最终调用LiveData的setValue方法,利用LiveData观察者模式的特性,数据改变时会自动通知观察者。

internal class LiveFragment : Fragment() {

    lateinit var liveData :MutableLiveData<PermissionResult>

    private val PERMISSIONS_REQUEST_CODE = 100

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        retainInstance = true    //旋转屏幕时保存Fragment状态
    }

    @TargetApi(Build.VERSION_CODES.M)
    fun requestPermissions(permissions: Array<out String>) {
        liveData = MutableLiveData()
        requestPermissions(permissions, PERMISSIONS_REQUEST_CODE)
    }


    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<out String>,
        grantResults: IntArray
    ) {
        if (requestCode == PERMISSIONS_REQUEST_CODE) {
            val denyPermission = ArrayList<String>()
            val rationalePermission = ArrayList<String>()
            for ((index, value) in grantResults.withIndex()) {
                if (value == PackageManager.PERMISSION_DENIED) {
                    if (shouldShowRequestPermissionRationale(permissions[index])) {
                        rationalePermission.add(permissions[index])
                    } else {
                        denyPermission.add(permissions[index])
                    }
                }
            }
            if (denyPermission.isEmpty() && rationalePermission.isEmpty()) {
                liveData.value = PermissionResult.Grant
            } else {
                if (rationalePermission.isNotEmpty()) {
                    liveData.value = PermissionResult.Rationale(rationalePermission.toTypedArray())
                } else if (denyPermission.isNotEmpty()) {
                    liveData.value = PermissionResult.Deny(denyPermission.toTypedArray())
                }
            }

        }
    }

}

在最后返回权限的权限处理选项时,使用kotlin的sealed关键字,来确保在项目里使用when时能安全的判断每个权限每种可能的情况。

sealed class PermissionResult {
    object Grant : PermissionResult()    //全部同意
    class Deny(val permissions: Array<String>) : PermissionResult()    //拒绝且勾选了不再询问,permissions——被拒绝的权限
    class Rationale(val permissions: Array<String>) : PermissionResult()    //只是拒绝,没有勾选不再询问,permissions——被拒绝的权限
}

代码已托管到github,欢迎star, 地址:

https://github.com/LGD2009/LivePermissions

项目已发布到jcenter,可直接引用。

3

使用方法

1.添加依赖

implementation 'com.ftd.livepermissions:livepermissions:1.0.0'

2.添加代码

//申请权限
LivePermissions(this).request(
    Manifest.permission.WRITE_EXTERNAL_STORAGE,
    Manifest.permission.READ_EXTERNAL_STORAGE,
    Manifest.permission.CAMERA
).observe(this, Observer {
    when (it) {
        is PermissionResult.Grant -> {  //权限允许
            Toast.makeText(this, "Grant", Toast.LENGTH_SHORT).show()
        }
        is PermissionResult.Rationale -> {  //权限拒绝
            it.permissions.forEach {s->                      
                println("Rationale:${s}")//被拒绝的权限
            }
            Toast.makeText(this, "Rationale", Toast.LENGTH_SHORT)
                .show()
        }
        is PermissionResult.Deny -> {   //权限拒绝,且勾选了不再询问
            it.permissions.forEach {s->
                println("deny:${s}")//被拒绝的权限
            }
            Toast.makeText(this, "deny", Toast.LENGTH_SHORT).show()
        }
    }
})

相关资料

LiveData 概览

https://developer.android.google.cn/topic/libraries/architecture/livedata

What are sealed classes in Kotlin?

https://stackoverflow.com/questions/50772328/what-are-sealed-classes-in-kotlin?r=SearchResults

推荐阅读

与“阿里”的flutter-go三剑合璧

我感觉我学了一个假的Android...

WebView,RecyclerView 多布局连贯滑动

Jetpack来了,利用LiveData “换掉” RxPermission

扫一扫  关注我的公众号

如果你想要跟大家分享你的文章,欢迎投稿~

┏(^0^)┛明天见!


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Linux二进制分析

Linux二进制分析

[美]瑞安 奥尼尔 / 棣琦 / 人民邮电出版社 / 2017-12-1 / CNY 59.00

二进制分析属于信息安全业界逆向工程中的一种技术,通过利用可执行的机器代码(二进制)来分析应用程序的控制结构和运行方式,有助于信息安全从业人员更好地分析各种漏洞、病毒以及恶意软件,从而找到相应的解决方案。 本书是一本剖析Linux ELF工作机制的图书,共分为9章,其内容涵盖了Linux环境和相关工具、ELF二进制格式、Linux进程追踪、ELF病毒技术、Linux二进制保护、Linux中的E......一起来看看 《Linux二进制分析》 这本书的介绍吧!

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具