内存优化(三),薪资翻倍

private float westXStart = 250;

private float westYStart = 300;

private float westXEnd = 150;

private float westYEnd = 300;

String colorStr[] = new String[]{

“#ffff00”,

“#ff3300”,

“#ccff00”,

“#ff00cc”,

“#ccffff”,

“#cc99ff”,

“#99ff66”,

“#993300”

};

private ValueAnimator valueAnimator;

private int currentColor = 0;

public IOSStyleLoadingView(Context context, AttributeSet attrs) {

super(context, attrs);

this.mContext = context;

this.mStrokeWidth = UIUtils.dp2px(this.mContext, 5);

}

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

Sample test1=new Sample(“测试1”);

Paint paint = new Paint();

paint.setAntiAlias(true);

paint.setStrokeWidth(this.mStrokeWidth);

paint.setStyle(Paint.Style.STROKE);

paint.setStrokeCap(Paint.Cap.ROUND);

Path p0 = new Path();

paint.setColor(Color.parseColor(colorStr[0]));

p0.moveTo(northwestXStart, northwestYStart);

p0.lineTo(northwestXEnd, northwestYEnd);

canvas.drawPath(p0, paint);

Path p1 = new Path();

paint.setColor(Color.parseColor(colorStr[1]));

p1.moveTo(northXStart, northYStart);

p1.lineTo(northXEnd, northYEnd);

canvas.drawPath(p1, paint);

Path p2 = new Path();

paint.setColor(Color.parseColor(colorStr[2]));

p2.moveTo(notheastXStart, notheastYStart);

p2.lineTo(notheastXEnd, notheastYEnd);

canvas.drawPath(p2, paint);

Path p3 = new Path();

paint.setColor(Color.parseColor(colorStr[3]));

p3.moveTo(eastXStart, eastYStart);

p3.lineTo(eastXEnd, eastYEnd);

canvas.drawPath(p3, paint);

Path p4 = new Path();

paint.setColor(Color.parseColor(colorStr[4]));

p4.moveTo(southeastXStart, southeastYStart);

p4.lineTo(southeastXEnd, southeastYEnd);

canvas.drawPath(p4, paint);

Path p5 = new Path();

paint.setColor(Color.parseColor(colorStr[5]));

p5.moveTo(southXStart, southYStart);

p5.lineTo(southXEnd, southYEnd);

canvas.drawPath(p5, paint);

Path p6 = new Path();

paint.setColor(Color.parseColor(colorStr[6]));

p6.moveTo(southwestXStart, southwestYStart);

p6.lineTo(southwestXEnd, southwestYEnd);

canvas.drawPath(p6, paint);

Path p7 = new Path();

paint.setColor(Color.parseColor(colorStr[7]));

p7.moveTo(westXStart, westYStart);

p7.lineTo(westXEnd, westYEnd);

canvas.drawPath(p7, paint);

}

@Override

protected void onAttachedToWindow() {

super.onAttachedToWindow();

startAnimation();

}

public void startAnimation() {

valueAnimator = ValueAnimator.ofInt(7, 0);

valueAnimator.setDuration(400);

valueAnimator.setRepeatCount(ValueAnimator.INFINITE);

valueAnimator.setInterpolator(new LinearInterpolator());

valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

@Override

public void onAnimationUpdate(ValueAnimator animation) {

if ((int) animation.getAnimatedValue() != currentColor){

String b[] = new String[colorStr.length];

for (int c = 0, size = colorStr.length - 1; c < size; c++) {

b[c + 1] = colorStr[c];

}

b[0] = colorStr[colorStr.length - 1];

colorStr = b;

invalidate();

currentColor = (int) animation.getAnimatedValue();

}

}

});

valueAnimator.start();

}

}

img

内存分配

这是一个看起来相对平滑的内存走势图,但是也能看出内存一直在增加,不知道为什么我的内存分配Allocations一直为0,希望看到的小伙伴留言解答一下。

上面的代码有三个问题:

1、不断创建String对象,如下代码

paint.setColor(Color.parseColor(color[0]));

点击进去看源码:

public static int parseColor(@Size(min=1) String colorString) {

if (colorString.charAt(0) == ‘#’) {

// Use a long to avoid rollovers on #ffXXXXXX

// 这里调用了String类的substring方法

long color = Long.parseLong(colorString.substring(1), 16);

if (colorString.length() == 7) {

// Set the alpha value

color |= 0x00000000ff000000;

} else if (colorString.length() != 9) {

throw new IllegalArgumentException(“Unknown color”);

}

return (int)color;

} else {

Integer color = sColorNameMap.get(colorString.toLowerCase(Locale.ROOT));

if (color != null) {

return color;

}

}

throw new IllegalArgumentException(“Unknown color”);

}

原来这里调用了String类的substring方法,我们都知道String类是不可变类,每一个字符串对应一个String对象,每次调用substring方法截取字符串就要新建一个String对象来接收截取后的值,所以我们选中的String对象就来自这里。

代码修改如下:

int[] colorInt = new int[colorStr.length];

// 构造方法中初始化

for (int i = 0; i < colorStr.length; i++) {

colorInt[i] = Color.parseColor(colorStr[i]);

}

2、不能再onDraw中创建对象

Path mPath = new Path();

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

// 把Paint、Path的创建移出去

mPath.reset();

paint.setColor(colorInt[(currentColor++)%8]);

mPath.moveTo(northwestXStart, northwestYStart);

mPath.lineTo(northwestXEnd, northwestYEnd);

canvas.drawPath(mPath, paint);

}

3、属性动画的addUpdateListener监听中不断创建数组

valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

@Override

public void onAnimationUpdate(ValueAnimator animation) {

if ((int) animation.getAnimatedValue() != currentColor){

// 记录每次回调的int值,去改变颜色的角标

currentColor = (int) animation.getAnimatedValue();

invalidate();

}

}

});

通过修改,内存非常稳定,没有了大量对象的创建。那我们来看一下是否有内存泄漏的问题呢?

使用Profiler工具dump一下,查看内存分配的具体信息,在使用MAT工具查看明细。

img

查看Activity是否有强引用

可以看到我们刚刚的自定义菊花Activity退出后一直存在强引用,造成内存泄漏。Activity的Context一直被自定义控件持有,再往上看IOSStyleLoadingViewIOSStyleLoadingView$1内部类持有。

img

引用关系

注意:

动画一直要记得停止

总结

这次面试问的还是还是有难度的,要求当场写代码并且运行,也是很考察面试者写代码
因为Android知识体系比较庞大和复杂的,涉及到计算机知识领域的方方面面。在这里我和身边一些朋友特意整理了一份快速进阶为Android高级工程师的系统且全面的学习资料。涵盖了Android初级——Android高级架构师进阶必备的一些学习技能。

附上:我们之前因为秋招收集的二十套一二线互联网公司Android面试真题(含BAT、小米、华为、美团、滴滴)和我自己整理Android复习笔记(包含Android基础知识点、Android扩展知识点、Android源码解析、设计模式汇总、Gradle知识点、常见算法题汇总。)

里面包含不同方向的自学编程路线、面试题集合/面经、及系列技术文章等,资源持续更新中…

总结

这次面试问的还是还是有难度的,要求当场写代码并且运行,也是很考察面试者写代码
因为Android知识体系比较庞大和复杂的,涉及到计算机知识领域的方方面面。在这里我和身边一些朋友特意整理了一份快速进阶为Android高级工程师的系统且全面的学习资料。涵盖了Android初级——Android高级架构师进阶必备的一些学习技能。

附上:我们之前因为秋招收集的二十套一二线互联网公司Android面试真题(含BAT、小米、华为、美团、滴滴)和我自己整理Android复习笔记(包含Android基础知识点、Android扩展知识点、Android源码解析、设计模式汇总、Gradle知识点、常见算法题汇总。)
[外链图片转存中…(img-yQKwBek2-1643891054624)]
里面包含不同方向的自学编程路线、面试题集合/面经、及系列技术文章等,资源持续更新中…

本文已被CODING开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》收录

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值