上期回顾

现象

Android 6.0 以下(正常显示)

Normal

Android 6.0(含)以上(有 Bug)

Bug

问题排查

时间线

  1. 起初在小米 4(Android 6.0)发现应用 A 正式预览版在某个页面暂无聊天不显示图片
  2. 对比三星 note4(Android 5.1)正常显示图片,怀疑是混淆问题
  3. 应用 A 正式预览版解除混淆,在小米 4 上还是不显示图片
  4. 在小米 4 上安装应用 A 的测试版本,以防代码变动导致的不显示图片,结果表明测试版本在小米 4 上还是不显示图片
  5. 在另外台 Android 6.0 手机上安装应用 A 正式预览版,发现图片也是不 显示,推断问题发生在 Android 6.0 上
  6. 进入代码调试阶段,加入断点和日志打印

为什么问题在测试版未发现,而在正式预览版才暴露?

测试关注点

问题推进

相关代码

/**
     * loadView 隐藏时停止播放动画,并设置张小图回收点资源
     * @param changedView
     * @param visibility
     */
    @Override
    protected void onVisibilityChanged(View changedView, int visibility) {
        // TODO Auto-generated method stub
        super.onVisibilityChanged(changedView, visibility);
        if (visibility == View.GONE) {
            Log.d("loadView", "onVisibilityChanged GONE");
            stopAnim();
            if(imgv_pic != null){
                imgv_pic.setImageResource(R.drawable.ic_user_page_indicator2);
                Log.d("loadView", "onVisibilityChanged GONE >> setImage");
            }
        }
    }

布局 xml 代码

<com.a.widget.LoadingView
    android:id="@+id/view_no_msg_data"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_centerInParent="true"
    android:visibility="gone">
</com.a.widget.LoadingView>

Android 6.0 以下执行顺序(含问题分析)>> 先 xml 再 java,针对android:visibility属性

  1. 先执行 onVisibilityChanged 方法,因为此时 View 未初始化所以imgv_pic = null,不会执行到设置 Image 的语句imgv_pic.setImageResource(R.drawable.ic_user_page_indicator2);
  2. 再初始化 View,再使用的时候设置为 VISIBLE,所以图片正常显示
D/loadView: onVisibilityChanged GONE
D/loadView: super init >> inflater.inflate:loadView
D/loadView: init view >> findViewById
D/loadView: init view >> setMode 
D/loadView: Visibility >> VISIBLE

Android 6.0(含)以上执行顺序(含问题分析)>> 先 java 再 xml,针对android:visibility属性

  1. 先初始化 View,并调用setMode方法设置 imgv_pic 的资源图片,此时 imgv_pic 不为空
  2. 再执行 onVisibilityChanged 方法,因为此时 imgv_pic 不为空,所以进入了 setImage 方法设置了一张小图(参见前面代码),等需要该 LoadingView 显示的时候,显示出来就看到只有暂无聊天这几个字,未发现有 ImageView(此时的 ImageView 是张小图,小到肉眼发现不了),所以此时有 Bug
D/loadView: super init >> inflater.inflate:loadView
D/loadView: init view >> findViewById
D/loadView: init view >> setMode 
D/loadView: onVisibilityChanged GONE
D/loadView: onVisibilityChanged GONE >> setImage
D/loadView: Visibility >> VISIBLE

额外收获

问题代码

if(imgv_pic != null){
    getRunningAppProcessInfo();
    imgv_pic.setImageResource(R.drawable.ic_user_page_indicator2);
    Log.d("loadView", "onVisibilityChanged GONE >> setImage");
    getRunningAppProcessInfo();
}

日志打印

I/memory: processName=com.a.b.c,pid=19116,uid=10604,memorySize=31992kb
D/loadView: onVisibilityChanged GONE >> setImage
I/memory: processName=com.a.b.c,pid=19116,uid=10604,memorySize=32056kb

解决方案

验证方案

在 Android 6.0(含)以上、Android6.0 以下版本中验证修改后的代码,均正常显示。

Tips


↙↙↙阅读原文可查看相关链接,并与作者交流