IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Android 学习之那些年我们遇到的BUG9:Lifecycle.Event.ON_RESUME 提前触发了 -> 正文阅读

[移动开发]Android 学习之那些年我们遇到的BUG9:Lifecycle.Event.ON_RESUME 提前触发了

BUG:自定义 View 中实现了 LifecycleObserver 接口,编写了一个 onResume(…) 函数,并给它加上了注解“@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)”,但是所在的 Fragment 还没有处于 onResume() 状态,View 的 onResume(…) 方法就触发了

产生的背景:

  1. 实现了 LifecycleObserver 接口的自定义 View
  2. 自定义 View 中有一个加了 @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) 注解的方法 onResume(…)
  3. 在 MainActivity 中有一个 ViewPager,里面承载了三个 Fragment
  4. 在第三个 Fragment 的布局中使用该自定义 View
  5. 启动应用后发生崩溃,查看错误日志,说 onResume(…) 中使用了未初始化的 ImageView
public class UserHeader extends ConstraintLayout implements LifecycleObserver {
		// ...
    private RoundedImageView roundedImageView;
    // ...
  	public UserHeader(Context context) {
        super(context);
        init(context, null);
    }
  	// ...
  	private void init(Context context, AttributeSet attrs) {
        // ...
        // 加载自定义布局
        LayoutInflater.from(context).inflate(R.layout.layout_xxx, this);
      	// ...
        if (getContext() instanceof XXXActivity) {
            ((XXXActivity) getContext()).getLifecycle().addObserver(this);
        }
        //实例化组件
        roundedImageView = (RoundedImageView) findViewById(R.id.xxx);
        // ...
    }
  
  	@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    public void onResume() {
        // ...
        if (!TextUtils.isEmpty(userString)) {
            // ...
        } else {
            // 发生崩溃的位置
            roundedImageView.setImageResource(mNotLoggedInHeader);
            // ...
        }
    }
}

排查过程:

  1. LifeCycle 的 ON_RESUME 触发了,说明其观察的 Context 的 onResume 触发了,控件是写在 Fragment 中,在没有仔细阅读自定义 View 的前提下,天真的认为是因为 Fragment 走了 onResume,导致触发,所以想起 Fragment 懒加载问题,打算去排查(其实 Fragment 要是真的触发了 onResume,那么 roundedImageView 也不会没有初始化了)
  • 检查 Fragment 的生命周期打印,发现并没有执行到 onResume
  • 检查 VP 的 adapter,确实使用了 BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT 那么说明只有当 VP 切换到第三个 Fragment 时,对应的它的 onResume 才会触发
  1. 既然不是 Fragment 的生命周期导致的 LifeCycle 的 ON_RESUME 触发,那说明调用 addObserver(…) 的对象另有其人,经过查看代码与打印日志,发现是承载 Fragments 的活动 MainActivity,这也不难理解崩溃造成的原因了:
  • 一启动应用,进入 MainActivity 后,它的 onResume 函数就触发了,进而出发了 View 的 onResume(…) 方法。
  • 那为什么在执行 View 的 onResume(…) 方法时 roundedImageView 没有初始化呢,原因在于 addObserver(this) 操作早于 findViewById(…) ,一旦 view 被 addObserver(…) 后,之前产生的事件都会一一触发,直接走了 View 的 onResume(…) 方法,而此时 roundedImageView 的初始化操作还在后面没有执行,先调用了 setImageResource(…) 方法,产生崩溃。

解决方法:

偷了个懒,将 addObserver(…) 操作放在了 findViewById(…) 之后,虽然暂时解决了,但还是存在隐患,万一哪天另外一个同事修改代码的时候,在后面写了初始化方法呢!但是由于是基础库改动需要十分小心而且没有太多时间深入研究,只好写上注释,??警告后人!!日后有时间,要好好考虑一下这个部分的实现了。

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-09-12 13:16:58  更:2021-09-12 13:17:28 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 16:58:03-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码