Android高级UI面试题汇总(含详细解析二十九)

Android并发编程高级面试题汇总最全最细面试题讲解持续更新中👊👊
👀你想要的面试题这里都有👀
👇👇👇

如何优化自定义View

这道题想考察什么?

考察同学对自定义View的注意点是否熟悉。

考生应该如何回答

降低刷新频率

为了提高view的运行速度,减少来自于频繁调用的程序的不必要的代码。从onDraw()方法开始调用,这会给你带来最好的回报。特别地,在onDraw()方法中你应该减少冗余代码,冗余代码会带来使你view不连贯的垃圾回收。初始化的冗余对象,或者动画之间的,在动画运行时,永远都不会有所贡献。
加之为了使onDraw()方法更有依赖性,你应该尽可能的不要频繁的调用它。大部分时候调用 onDraw()方法就是调用invalidate()的结果,所以减少不必要的调用invalidate()方法。有可能的,调用四种参数不同类型的invalidate(),而不是调用无参的版本。无参变量需要刷新整个view,而四种参数类型的变量只需刷新指定部分的view。这种高效的调用更加接近需求,也能减少落在矩形屏幕外的不必 要刷新的页面。
另外一个十分耗时的操作是请求layout。任何时候执行requestLayout(),会使得Android UI系统去遍历整个View的层级来计算出每一个view的大小。如果找到有冲突的值,它会需要重新计算很多次。另外需要尽量保持View的层级是扁平化的,这样对提高效率很有帮助。 如果你有一个十分复杂的界面,你应该写一个自定义的ViewGroup类来表现它的布局。不同于内置的 view类,你的自定义view能关于尺寸和它子控件的形状做出应用特定的假想,同时避免通过它子类来 计算尺寸。这圆图例子显示怎样作为自定义view一部分来继承ViewGroup类,圆图有它子view类, 但是从来都不测量他们。相反地,它直接地通过自己自定义的布局算法来设定他们的尺寸大小。
如果你有一个复杂的UI,你应该思考写一个自定义的ViewGroup来执行他的layout操作。与内置的view不同,自定义的view可以使得程序仅仅测量这一部分,这避免了遍历整个view的层级结构来计算大小。这个PieChart 例子展示了如何继承ViewGroup作为自定义view的一部分。PieChart 有子views,但是它从来不测量它们。而是根据他自身的layout法则,直接设置它们的大小。

使用硬件加速

作为Android3.0,Android2D图表系统可以通过大部分新的Android装置自带GPU(图表处理单元)来增加,对于许多应用程序 来说,GPU硬件加速度能带来巨大的性能增加,但是对于每一个应用来讲,并不都是正确的选择。Android框架层更好地为你提供了控制应用程序部分硬件 是否增加的能力。
怎样在你的应用,活动,或者窗体级别中使用加速度类,请查阅Android开发者指南中的Hardware Acceleration类。注意到在开发者指南中的附加说明,你必须在你的AndroidManifest.xml 文件中的中将应用目标API设置为11或者更高的级别。
一旦你使用硬件加速度类,你可能没有看到性能的增长,手机GPUs非常擅长某些任务,例如测量,翻转,和平移位图类的图片。特别地,他们不擅长其他的任务,例如画直线和曲线。为了利用GPU加速度类,你应该增加GPU擅长的操作数量,和减少GPU不擅长的操作数量。

减少过度渲染

当UI之间有重叠的时候,虽然后面的UI用户看不到,但是还是会绘制,这部分的绘制就是过度渲染。
一般通过Canvas.clipXxx 方法来裁剪区域,让看不到的地放不绘制,从而达到减少过度渲染的目的。

初始化时创建对象

不要在onDraw方法内创建绘制对象,一般都在构造函数里面初始化对象;

@Override
protected void onDraw(Canvas canvas) {
    if (getDrawable() == null) {
        return;
    }
    setUpShader();
    canvas.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG));
    if (mType == TYPE_ROUND) {
        canvas.drawRoundRect(mRoundRect, mBorderRadius, mBorderRadius, mBitmapPaint);
    } else {
        canvas.drawCircle(mRadius, mRadius, mRadius, mBitmapPaint);
    }
}
状态的存储与恢复

如果内存不足,而正好我们的Activity置于后台,不幸被重启,或者用户旋转屏幕造成Activity重启,我们的View应该也能尽可能的去保存自己的属性。

@Override
protected Parcelable onSaveInstanceState() {
    Bundle bundle = new Bundle();
    bundle.putParcelable(STATE_INSTANCE, super.onSaveInstanceState());
    bundle.putInt(STATE_TYPE, mType);
    bundle.putInt(STATE_BORDER_RADIUS, mBorderRadius);
    return bundle;
}
 
@Override
protected void onRestoreInstanceState(Parcelable state) {
    if (state instanceof Bundle) {
        Bundle bundle = (Bundle) state;
        super.onRestoreInstanceState(((Bundle) state).getParcelable(STATE_INSTANCE));
        this.mType = bundle.getInt(STATE_TYPE);
        this.mBorderRadius = bundle.getInt(STATE_BORDER_RADIUS);
    } else {
        super.onRestoreInstanceState(state);
    }
}

由于面试题内容比较多,篇幅有限,资料已经被整理成了PDF文档,有需要2023年Android中高级最全面试真题答案 完整文档的可扫描下方卡片免费获取~

PS:(文末还有使用ChatGPT机器人小福利哦!!大家不要错过)

目录

img

第一章 Java方面

  • Java基础部分
  • Java集合
  • Java多线程
  • Java虚拟机

img

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值