• AndroidSensor的exiting main sensor thread问题


    使用sensor的时候,有一个问题困扰了我很多天。

    每次打开app读取sensor数值,只要过了60秒,logcat就会出现:

    更奇怪的是,只要按过按键之后,出错时间就会重新被更新为60秒之后。

    在反复检查了driver和hal的代码并确认无误之后,终于不得不把目光转向了更上层。

    由于简短的jni代码只是负责调用,并没有再添加多少处理代码;而app代码非常简单,所以把问题锁定在了framework层。

    根据报错的调试信息,可以快速地通过ctrl + F定位到SensorManager.java

    所以问题出错的原因是sListeners.isEmpty()返回true,而sListeners的定义是:

    static final ArrayList<ListenerDelegate> sListeners = new ArrayList<ListenerDelegate>();

    通过在网上不多关于Android Sensor的搜索,得知isEmpty的原因是Listener的列表为空。

    可是为什么过了60s列表就会被清空呢?在线程中查看了很多次,都没有发现移除的相关代码。不管是和control_activate、control_wake还是enableSensor相关的代码都没有影响到sensor列表。在偶然的查看代码中,突然想到了查找“remove”看是否有移除sensor的方法。最后,终于找到了:

    根据注释很明显就是这里导致了sListeners.isEmpty()。再一看,居然是在unregisterListener方法中调用。看来是因为unregisterListener被调用导致了出错,再回到app代码查看,才发现原来是Activity的onPause方法中调用了unregistereListener()。

    在onPause中加了句调试信息,果然,没动触摸屏或键盘60秒后,onPause就会被调用。到了这个时候,只能怪自己不去理解透彻Activity的工作原理,照着实例代码写直接在onPause中加了不该加的代码。

    等等!我之前自己专门加上的unregisterListener调试信息不是在一开始,就跟随报错一起输出了吗?为什么忽略了这条信息而错误地在其他地方查错?回想一下,其实一开始也注意到了,只是这条信息写得和系统的报错信息实在是太像了,让我误以为是framework内某段代码的判断输出。

    所以,这次调试得到了几个经验:

    1. 个人的调试信息写得特别一点,要一眼就能看出来是自己写的,而不会被埋没在大量调试输出中;
    2. 内核或Android系统提供的代码出错概率不大,优先考虑自己的代码和接口有什么不符合;
    3. 即使是很短的小代码,也有可能导致出错。
  • 相关阅读:
    Docker简介,安装,配置
    Centos7给 root 账户开通ssh权限
    [转载]Hyper-v 安装CentOS 7
    软件开发_六大原则
    php函数名后冒号(:)+数据类型(返回值类型限制/php新特性)
    MySQL--事务介绍
    MySQL存储引擎
    leetcode刷题笔记300题 最长上升子序列
    leetcode刷题笔记299题 猜数字游戏
    **leetcode刷题笔记四 两个有序序列的中位数**
  • 原文地址:https://www.cnblogs.com/jacobchen/p/2726828.html
Copyright © 2020-2023  润新知