视图焦点问题


ViewTreeObserver详解

1. 在使用时为防止多次计算焦点视图的长宽造成的焦点问题,应该判断焦点视图是否是第一次计算长宽,如果不是第一次,记得remove掉, 具体代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
if (firstCalc && focusView.getWidth() == 0 && focusView.getHeight() == 0)
{
/**
* recalc focus view width and height
*/
final ViewTreeObserver observer = focusView.getViewTreeObserver();
observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
focusView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
//回调自身的方法,false代表firstCalc不是首次计算
mySelfView(focusView, moveView, scale, false);
}
});
return;
}

2. 具体方法详解

(1)interface ViewTreeObserver.OnGlobalLayoutListener

  • 当在一个视图树中全局布局发生改变或者视图树中的某个视图的可视状态发生改变时,所要调用的回调函数的接口类

    (2)

    /**注册一个回调函数,当在一个视图树中全局布局发生改变或者视图树中的某个视图的可视状态发生改变时调用这个回调函数。
    • *参数 listener 将要被添加的回调函数
    • *异常 IllegalStateException 如果isAlive() 返回false

*/

  •   public void addOnGlobalLayoutListener (ViewTreeObserver.OnGlobalLayoutListener listener)

    (3)

    /**移除之前已经注册的全局布局回调函数。
  •    *参数 victim 将要被移除的回调函数
  •    异常 IllegalStateException 如果isAlive() 返回false   /
  •   public void removeGlobalOnLayoutListener (ViewTreeObserver.OnGlobalLayoutListener victim)

如何把笔记推送到gitHub的博客上

1. 写一篇MarkDown的笔记,在顶部加上标题和时间,如下

1
2
3
4
---
title: 视图焦点问题
date: 2017-09-14 14:54:21
---
  • 注:标题和时间都可更改

    2. 进入你本地的博客目录下,我的在D:\ly931126.github.io\source_posts ,将写好的markdown笔记放入该目录下

3. 在D:\ly931126.github.io点击鼠标右键选择 Git bash here ,然后输入 命令

1
hexo clean && hexo g && hexo d

4.进入你的博客网页查看是否推送成功

Markdown的使用方法

目录

  • 注:要实现目录跳转,方式一:中括号和小括号中的内容要一致;
  • 方式二:中括号里的字母可以任意字母大写,中括号内容没有要求, ,小括号的字母有大写则不能跳转

one

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
忘了有多久
再没听到你
对我说你 最爱的故事
我想了很久
我开始慌了
是不是我又做错了什么
你哭着对我说
童话里都是骗人的
我不可能 是你的王子
也许你不会懂
从你说爱我以后
我的天空 星星都亮了
我愿变成童话里
你爱的那个天使
张开双手
变成翅膀守护你

two

  • 每个人的人生都有一万种可能

three


地球是圆的,走着走着就遇见了

four

百度

five

图片

1
2
3
在github上,图片的简单跳转,(注:在有道云上跳转不了)
模式 ![图片名](图片链接)
注:!必须为英文状态下的

six

这种方式可以放两个相同的图片链接,就能跳转
模式:
图片名
注:链接1和链接2可以相同

1
2
3
4
5
6
7
8
seven
---
```
GitHub上放动态图的方法,将.gif的图片放在项目的根目录下,然后在README.md文件中调用时,可以设置gif动画的尺寸
用命令
<img src="skin_sc.gif" width="320px"/>
即可

  • 在有道云上显示gif动画,可以

ELEVEN

目录

Android性能优化工具 Memory Monitor

Memory Monitor

Memory Monitor是AS自带的内存监视工具,可以实时显示程序内存消耗情况,并且提供了内存分析工具,帮助开发者程序中内存泄漏问题。如下图,蓝色代表分配的内存,灰色代表可以分配的。

image
image

  • A:initiate GC 手动触发GC操作;
  • B:Dump Java Heap 获取当前的堆栈信息,生成一个.hprof文件,AndroidStudip会自动使用HeapViewer打开;一般用于操作之后检测内存泄漏的情况;
  • C:Start Allocation Tracking 内存分配追踪工具,用于追踪一段时间的内存分配使用情况,能够知道执行一些列操作后,有哪些对象被分配空间。一般用于追踪某项操作之后的内存分配,调整相关的方法调用来优化app性能与内存使用;
  • D:剩余可用内存;
  • E:已经使用的内存。
    Memory Monitor提供了三个强大的工具,下面我们通过这些工具来分析应用内存使用情况

Dump Java Heap

这个工具用于生成Java堆使用日志文件,里面包含了Java 对象在堆内存的占用情况,以及内存泄漏情况

1.点击如图按钮,AS将会生成日志文件

image

image

打开这个日志文件,有几块区域 我们来一块块分析

(1)Class Name: Java 堆中的类

image

里面有几个参数,

  • Total Count 该类的实例个数
  • Heap Count 选定的Heap中实例的个数
  • Sizeof 每个实例占用的内存大小
  • Shallow Size 所有该类的实例在heap中占用的内存大小
  • Retained Size 该类的所有实例可支配的内存大小

下面是我的一些总结
byte[] ,大多数时候是因为缓存了图片引起的FinalizerReference ,是因为某些引用无法GC,始终存在于内存中
(2)Instance

image

在这个窗口,我们可以看到对象实例,工具给出了对象占用的内存空间大小,以及对象的内容

(3)Reference Tree

image

这个我们可以看到对象的引用关系树,我们可以分析对象中的哪些变量占用的内存过大,从而优化代码。

(4)Analyzer Tasks

image

这是非常有用的一个日志,可以分析因为强引用无法销毁的对象,特别是Activity对象,在程序中为错误的使用Context,handler,都会造成内存泄漏,泄漏的地方在这里可以展示出来。

分析方法 (重点)

通过各种爬坑总结了以下方法,最快,最准的找到内存泄漏的地方。

step1:监控Memory Monitor内存情况,如果内存持续增高,可能发生泄漏,如果内存突然减少,可能发生GC。如果你在关闭一个Activity时,内存几乎没有减少,很可能这个activity就没有被回收。这时候我们点击Dump Java Heap。

step2:打开Analyzer Tasks窗口,勾选左上角你要分析的类型,点击绿色箭头按钮,生成日志,我们从上图可以看到有5个Activity对象没有回收,这些Activity就是我们要找的对象。

step3:点击一个Activity,我们看Reference Tree窗口

image

在这个窗口中,主要找两种变量,一个是Index,一个占用大的变量

Index是Activity中引用了这个Activity的对象,从上图中,我们1个个展开,我们可以看到是类AppManager中的变量mActivityStack中引用了这个Activity对象,并且没有在Activity销毁的时候释放这个引用。

我们通过可以找到占用大的变量,可以找到一些内存泄漏的根本原因,比如你的Activity有一个很大的bitmap对象,可能会导致系统的GC出现问题,无法回收。这些大变量我们要小心使用,比较严谨的方式就是在Activity 的onDestroy方法手动销毁。

step4:分析Class Name。通过前两步,我们可以基本解决因为引用问题导致Activity无法回收,但是OOM还有一个很大的原因就是图片导致的,我们查看Class Name,如果byte[]占用内存过大,就是图片缓存导致的,这个时候需要处理图片缓存了。处理的方法有很多,不同的图片加载库有不同的处理方法,推荐使用成熟的库,如glide,picasso ,fresco

Memory Monitor中还有一个按钮:Allocation Tracking,这个是分析应用线程占用资源的,也是一个非常棒的工具,生成的日志简单明了,可以试试。

image

总结

Memory Monitor可以很好的分析应用的内存问题,但是内存优化是一条漫漫长路,出现内存泄漏的情况有非常多,我们只要在不停的挖坑和爬坑中总结。后面会继续总结内存泄露自动探测神器——LeakCanary 以及分析内存的强大助手MAT(memory Analyzer Tool)