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机器人小福利哦!!大家不要错过)
目录
第一章 Java方面
- Java基础部分
- Java集合
- Java多线程
- Java虚拟机