深入源码系列:聊聊android属性动画执行线程问题(invalidate(false))

前言

这篇博文是为了解决一个问题,在之前的博客已经提过了,就是属性动画的执行结束的回调,不是在主线程。
首先,阅读这篇文章,大家一定要有一个基础,就是,android不一定只能在主线程才能更新UI。这方面我不多说,想多了解的同学大家自己去查阅博客。
下面回到我们这个问题,在探究源码前,我们先来验证一下
(多说一句,android动画相当在计算位置坐标的时候相当蛋疼,所以楼主一直不愿意做涉及到ui的动画,但是ConstraintLayout给了一个直接通过xml可以执行的动画,相当爽,晚点咱们再聊聊)
代码很简单,就不写了,就是在普通的线程里面,执行动画,毫无意外崩溃了,接下来再看看报错
在这里插入图片描述
没错,报错了,但是,提示的却不是必须在UI线程调用,而是,线程里面必须又Looper?
大家有没有想到,哪个线程里面是有Looper的呢?没错,就是HandlerThread,这是google给我封装好的线程,我们来试试。

        val mhandler = Handler(handlerT.looper);
        mhandler.post() {
   
            iv.animate().scaleX(2f).scaleY(2f).setDuration(1000)
            Thread.sleep(100000)
//        ObjectAnimator.ofInt(constraintlayou_root, "translationX", 0, 100, 0, 100)
//            .setDuration(3000)
//            .start();
        }

毫不意外,这里顺利运行了。关于animate()大家可以了解下,是Google给我们封装好的动画,很好用。并且,大家可以发现,我再这个线程里面调用了,Thread.sleep,但是,动画完全没有任何影响。这是为什么呢?
下面就要进入我们的源码分析时间了。
先给出一个写的比较好的博客
Android 属性动画详解与源码分析
但这这个博客存在一个问题,就是分析到jni或者反射调用后就没有接着往下分析了。所以楼主不会从0开始继续分析这个地方,而是调出关键节点,梳理清楚,这样在很长一段时间后,不需要看长篇大论的源码,就能快速回忆起关键的地方。
首先,略过中间部分不谈,最关键的,就是,通过jni或者反射调用到scaleX之后,又发生了什么。
这里给一个debug栈的截图
在这里插入图片描述
可以看出,这里走的是jni调用。然后走到了invalidateViewProperty(),该函数如下


    /**
     * Quick invalidation for View property changes (alpha, translationXY, etc.). We don't want to
     * set any flags or handle all of the cases handled by the default invalidation methods.
     * Instead, we just want to schedule a traversal in ViewRootImpl with the appropriate
     * dirty rect. This method calls into fast invalidation methods in ViewGroup that
     * walk up the hierarchy, transforming the dirty rect as necessary.
     *
     * The method also handles normal invalidation logic if display list properties are not
     * being used in this view. The invalidateParent and forceRedraw flags are used by that
     * backup approach, to handle these cases used in the various property-setting methods.
     *
     * @param invalidateParent Force a call to invalidateParentCaches() if display list properties
     * are not being used in this view
     * @param forceRedraw Mark the view as DRAWN to force the invalidation to propagate, if display
     * list properties are not being used in this view
     */
    @UnsupportedAppUsage
    void invalidateViewProperty(boolean invalidateParent, boolean forceRedraw) {
   
        if (!isHardwareAccelerated()
                || !mRenderNode.hasDisplayList()
                || (mPrivateFlags & PFLAG_DRAW_ANIMATION) != 0) {
   
            if (invalidateParent) {
   
                invalidateParentCaches();
            }
            if (forceRedraw) {
   
                mPrivateFlags |= PFLAG_DRAWN; // force another invalidation with the new orientation
            }
            <
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值