iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >Android开发Viewbinding委托怎么实现
  • 829
分享到

Android开发Viewbinding委托怎么实现

2023-07-02 11:07:48 829人浏览 安东尼
摘要

本篇内容介绍了“Android开发Viewbinding委托怎么实现”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!从Crash到有意思的源码

本篇内容介绍了“Android开发Viewbinding委托怎么实现”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

    从Crash到有意思的源码

    委托模式是软件设计模式中的一项基本技巧。在委托模式中,有两个对象参与处理同一个请求,接受请求的对象将请求委托给另一个对象来处理。

    Kotlin 直接支持委托模式,更加优雅,简洁。Kotlin 通过关键字 by 实现委托。

    上述是kotlin对于委托的释义,Viewbinding委托就是把生成Viewbinding实例的过程交给委托类去完成,然后让使用方可以忽略掉其中的细节,是一种非常好玩的模式了。

    但是由于Viewbinding的特殊性,它其实就会和当前的lifecycle绑定在一起。因为我们要在销毁的情况下把实例重置为空。否则当我们页面重新生成的情况下,就会出现view并不是当前的页面的困扰。

    作者在定义的时候就将Viewbinding委托获取的实例定义为了非空,这里我和我的同事其实是存在一些分歧的,我认为非空其实挺合理的,但是对方并不认为。

    恰巧这种空非空的问题,在实际的使用中就出现了很多不可预期的crash问题。比如说在一个异步操作中获取viewbinding实例然后进行赋值操作,就会出现空指针异常。另外由于使用的是lifecycle的页面销毁方法,如果我们复写了销毁方法之后在设置这个值,也会出现崩溃问题。

    上述问题我在几个我之前参考的库中其实都发现了对应的问题。我参考了Binding,还有之前彭旭说的那个也有类似的情况。

    另外在fragment中,其实问题尤其的明显。因为我们很多时候使用的fragment相关的LifecycleOwner是fragment本身,但是Android官方其实推荐我们使用的是fragment内部的view相关的LifecycleOwner。因为fragment相比较于activity,存在的问题就是多了几个生命周期,比如createView,和onDestroyView。其中出现最多问题的也就是onDestroyView和onDestroy。

    有趣的代码

    接下来我们看下这个作者是如何解决这些奇奇怪怪的问题的哦。

    private class FragmentViewBindingProperty<in F : Fragment, out T : ViewBinding>(    private val viewNeedInitialization: Boolean,    viewBinder: (F) -> T,    onViewDestroyed: (T) -> Unit,) : LifecycleViewBindingProperty<F, T>(viewBinder, onViewDestroyed) {    private var fragmentLifecycleCallbacks: FragmentManager.FragmentLifecycleCallbacks? = null    private var fragmentManager: Reference<FragmentManager>? = null    // 赋值操作    override fun getValue(thisRef: F, property: KProperty<*>): T {        val viewBinding = super.getValue(thisRef, property)        reGISterFragmentLifecycleCallbacksIfNeeded(thisRef)        return viewBinding    }    private fun registerFragmentLifecycleCallbacksIfNeeded(fragment: Fragment) {        if (fragmentLifecycleCallbacks != null) return        val fragmentManager = fragment.parentFragmentManager.also { fm ->            this.fragmentManager = WeakReference(fm)        }        fragmentLifecycleCallbacks = ClearOnDestroy(fragment).also { callbacks ->            fragmentManager.registerFragmentLifecycleCallbacks(callbacks, false)        }    }    override fun isViewInitialized(thisRef: F): Boolean {        if (!viewNeedInitialization) return true        if (thisRef !is DialogFragment) {            return thisRef.view != null        } else {            return super.isViewInitialized(thisRef)        }    }    override fun clear() {        super.clear()        fragmentManager?.get()?.let { fragmentManager ->            fragmentLifecycleCallbacks?.let(fragmentManager::unregisterFragmentLifecycleCallbacks)        }        fragmentManager = null        fragmentLifecycleCallbacks = null    }    override fun getLifecycleOwner(thisRef: F): LifecycleOwner {        try {            return thisRef.viewLifecycleOwner        } catch (ignored: IllegalStateException) {            error("Fragment doesn't have view associated with it or the view has been destroyed")        }    }    // 有意思的代码    private inner class ClearOnDestroy(        fragment: Fragment    ) : FragmentManager.FragmentLifecycleCallbacks() {        private var fragment: Reference<Fragment> = WeakReference(fragment)        override fun onFragmentDestroyed(fm: FragmentManager, f: Fragment) {            // Fix for destroying view for case with issue of navigation            if (fragment.get() === f) {                postClear()            }        }    }}

    从上述代码上我们可以看出来,其中获取的LifecycleOwner就是我上文说的viewLifecycleOwner。这个就其实已经非常精彩了。

    另外我们可以看下他在内部定义了ClearOnDestroy这个类,然后当onFragmentDestroyed触发的时候调用postClear方法。而这个方法就是解决当我们在Destroyed中还执行了ViewBinding内的对象的操作的空指针问题。

    经典面试题的真实使用场景,Handler.post执行。很多人觉得Handler相关的面试题都是八股文,这次我们就通过这个真是场景来给大家说说这个有意思的问题。

    首先从onFragmentDestroyed方法会执行在Fragment本身的onDestroyView之前,原来我们会在这个方法下执行引用清空的操作。然后当onDestroyView执行的时候就会出现空指针异常了。那么Lifecycle有没有提供一个在onDestroyView之后的方法呢?我们是不是可以考虑自己造一个呢?面试中,我们知道所有生命周期方法都是有主线程Handler来负责调度的,这也就是说活我么可以把生命周期方法认为就是一个Message,当onFragmentDestroyed执行的时候,onDestroyView也已经被添加到主线程的MessageQueue中,这个时候我们在post一个runnable,那么他的排序规则上来说,就必然在onDestroyView之后了。

    另外一些有意思的地方

    这个库另外一个优点就是他同时支持反射和非反射的写法。同时也支持了Activity,Fragment,View,FragmentDialog,ViewHolder等等。反射写法是基于非反射写法的,所以也保证了底层库的一致性。

        //非反射写法    private val viewBinding by viewBinding(ViewProfileBinding::bind)    //反射写法    private val viewBinding: ItemProfileBinding by viewBinding()

    同时他的反射相关的混淆配置文件也非常有意思。

    allowoptimization 指定对象可能会被优化,即使他们被keep选项保留。所指定对象可能会被改变(优化步骤),但可能不会被混淆或者删除。该修饰符只对实现异常要求有用。

    -keep,allowoptimization class * implements androidx.viewbinding.ViewBinding {    public static *** bind(android.view.View);    public static *** inflate(...);}

    它只会keep实现了ViewBinding的类的bind和inflate方法。因为ViewBinding会将所有的xml转化成一个类实例,如果不删除掉没有实际被调用的类的情况下就会导致dex包变大,大家对于包体积优化都是有追求的吗。然后用了-keep,allowoptimization,这样在混淆的代码优化过程中就可以删除掉没有被调用的ViewBinding类了。

    “Android开发Viewbinding委托怎么实现”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!

    --结束END--

    本文标题: Android开发Viewbinding委托怎么实现

    本文链接: https://www.lsjlt.com/news/341635.html(转载时请注明来源链接)

    有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

    本篇文章演示代码以及资料文档资料下载

    下载Word文档到电脑,方便收藏和打印~

    下载Word文档
    猜你喜欢
    • Android开发Viewbinding委托怎么实现
      本篇内容介绍了“Android开发Viewbinding委托怎么实现”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!从Crash到有意思的源码...
      99+
      2023-07-02
    • Android开发Viewbinding委托实例详解
      目录背景从Crash到有意思的源码有趣的代码另外一些有意思的地方结尾背景 前一阵子我们在使用viewbinding的委托的时候碰到了点crash问题,然后发现了一个比较有意思的解决方...
      99+
      2024-04-02
    • C#的Func委托怎么实现
      本篇内容介绍了“C#的Func委托怎么实现”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、什么是Func委托Func委托代表有返回类型的委...
      99+
      2023-06-29
    • ios委托模式怎么实现
      本篇内容介绍了“ios委托模式怎么实现”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!Cocoa Touch框架下使用大量使用委托(deleg...
      99+
      2023-07-05
    • jQuery中怎么实现事件委托
      jQuery中怎么实现事件委托,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。javascript的事件模型,采用"冒...
      99+
      2024-04-02
    • JavaScript中怎么实现事件委托
      JavaScript中怎么实现事件委托,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。事件是对象发送的消息,以发信号通知操作的发生。委托是可...
      99+
      2024-04-02
    • Android开发之Kotlin委托的原理与使用详解
      目录前言一、接口/类委托二、属性委托三、延迟委托四、观察者委托五、Map委托总结前言 在设计模式中,委托模式(Delegate Pattern)与代理模式都是我们常用的设计模式(Pr...
      99+
      2023-03-23
      Kotlin委托原理 Kotlin委托使用 Android Kotlin委托 Kotlin委托
    • js中的事件委托怎么实现
      在JavaScript中,可以通过事件委托来简化事件处理程序的绑定和管理。事件委托是将事件处理程序绑定到其父元素,然后通过冒泡机制来...
      99+
      2023-09-29
      js
    • C++怎么用boost.signal实现多播委托
      本篇内容主要讲解“C++怎么用boost.signal实现多播委托”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“C++怎么用boost.signal实现多播委托”吧!boost.signal提供...
      99+
      2023-07-02
    • 怎么在JavaScript中实现事件委托
      怎么在JavaScript中实现事件委托?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。事件委托利用事件冒泡,指定一个事件处理程序,管理一系列的所有事件事件委托利用DOM元素...
      99+
      2023-06-15
    • Android开发之Kotlin委托的原理与使用方法是什么
      今天小编给大家分享一下Android开发之Kotlin委托的原理与使用方法是什么的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧...
      99+
      2023-07-05
    • C#委托实现的步骤是什么
      C#委托的实现步骤如下:1. 定义委托类型:使用`delegate`关键字定义一个委托类型,指定委托的返回值类型和参数列表。2. 创...
      99+
      2023-09-09
      C#
    • JavaScript中怎么实现事件代理和委托
      JavaScript中怎么实现事件代理和委托,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。JavaScript事件代理首先介绍...
      99+
      2024-04-02
    • C++委托和消息反馈模板怎么实现
      本篇内容介绍了“C++委托和消息反馈模板怎么实现”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!继承+多态乍一看是理所当然的选择,库中的类把响...
      99+
      2023-06-17
    • C#中怎么利用委托实现异步调用
      这篇文章将为大家详细讲解有关C#中怎么利用委托实现异步调用,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。委托实现C#异步调用的步骤:定义委托。将要进行异步调用的方法“实例化”到定义的委托。在...
      99+
      2023-06-17
    • Javascript 中怎么实现事件流和事件委托
      今天就跟大家聊聊有关Javascript 中怎么实现事件流和事件委托,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。javascript 事件流和事件...
      99+
      2024-04-02
    • 事件委托模式怎么在java项目中实现
      这篇文章将为大家详细讲解有关事件委托模式怎么在java项目中实现,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。java实现事件委托模式的实例详解举例说明:一个班级,有两类学生,A类:不学习,...
      99+
      2023-05-31
      java 事件委托模式 ava
    • Android开发怎么实现Application跳出dialog
      本文小编为大家详细介绍“Android开发怎么实现Application跳出dialog”,内容详细,步骤清晰,细节处理妥当,希望这篇“Android开发怎么实现Application跳出dialog”文章能帮助大家解决疑惑,下面跟着小编的...
      99+
      2023-07-02
    • Android开发中怎么实现Activity切换
      今天就跟大家聊聊有关Android开发中怎么实现Activity切换,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。具体如下:这里要实现的目的是:有3个Activity: A,B,C,...
      99+
      2023-05-31
      android activity roi
    • 怎么在c#中利用委托事件实现多线程通信
      本篇文章为大家展示了怎么在c#中利用委托事件实现多线程通信,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。在研究c# 线程之间通信时,发现传统的方法大概有三种:全局变量,由于同一进程下的多个进程之间共...
      99+
      2023-06-14
    软考高级职称资格查询
    编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
    • 官方手机版

    • 微信公众号

    • 商务合作