写点什么

Android 面试主题整理合集(一),android 开发前景

用户头像
Android架构
关注
发布于: 刚刚

7.invalidate 与 requestLayout 区别


============================


  • view 调用 invalidate 将导致当前 view 的重绘,viewGroup 调用 invalidate 会使 viewGroup 的子 view 调用 draw

  • requestLayout 方法只会导致当前 view 的 measure 和 layout,而 draw 不一定被执行。只有当 view 的位置发生改变才会执行 draw 方法


8.View 和 ViewGroup 区别


==================


  • ViewGroup 的 onInterceptTouchEvent 默认返回 false,即不拦截事件,View 没有拦截事件方法,View 默认时消耗事件的

  • ViewGroup 默认不会调用 onDraw 方法,View 默认会调用 onDraw 方法。可以通过 setWillNotDraw(boolean willNotDraw)来指定是否调用 onDraw 方法


/**


  • If this view doesn't do any drawing on its own, set this flag to

  • allow further optimizations. By default, this flag is not set on

  • View, but could be set on some View subclasses such as ViewGroup.

  • Typically, if you override {@link #onDraw(android.graphics.Canvas)}

  • you should clear this flag.

  • @param willNotDraw whether or not this View draw on its own


*/


public void setWillNotDraw(boolean willNotDraw) {


setFlags(willNotDraw ? WILL_NOT_DRAW : 0, DRAW_MASK);


}


9.android 版本新特性


==============


  • 5.0 引入 Material Design 主题

  • 6.0 运行时权限

  • 7.0 文件读写权限适配 FileProvider 移除了对 Apache HTTP 客户端的支持,建议使用 HttpURLConnection 代替。继续使用 Apache HTTP API,必须先在 build.gradle 文件中配置: android { useLibrary 'org.apache.http.legacy' } 复制代码

  • 8.0 为所有通知分配渠道 app 内更新下载好的 apk 文件,需要用户开启未知应用安装权限

  • 9.0 使用安全的网络访问,如果使用 http 请求会报错。Android 9.0 网络适配

  • 10.0 存储空间分区存储,沙盒模式


10.Android 中一张图片占据的内存大小是如何计算


===========================


  • 图片来源是 res 内的不同资源目录时,系统会根据设备当前的 dpi 值以及资源目录所对应的 dpi 值,做一次分辨率转换,规则如下:新分辨率 = 原图横向分辨率 * (设备的 dpi / 目录对应的 dpi ) * 原图纵向分辨率 * (设备的 dpi / 目录对应的 dpi )

  • 其他图片的来源,如磁盘,文件,流等,均按照原图的分辨率来进行计算图片的内存大小

  • 一张图片占用的内存大小的计算公式:分辨率 * 像素点大小;但分辨率不一定是原图的分辨率,需要结合一些场景来讨论,像素点大小就几种情况:ARGB_8888(4B)、RGB_565(2B) 等等


11.APP 启动速度优化


============


  • 用 adb 命令可以检测启动时间,示例如下:


adb shell am start -W [packageName]/[.MainActivity]


./adb shell am start -W "com.hchstudio.dict"/".MainActivity"


WaitTime 为我们所关注的启动时间


  • app 的启动流程,主要需要减少 Application 和启动界面的 onCreate 方法

  • 的 app 首页主题样式加上 android:windowBackground,放一下 app 的背景图片,这样即使 app 启动慢,也会首先加载背景,这样就会给用户造成一种假象,认为是 app 已经启动


<style name="AppTheme.Launcher">


<item name="android:windowBackground">@color/colorLauncher</item>


</style>


12.内存抖动


=======


内存抖动是由于短时间内有大量对象进出新生区导致的,它伴随着频繁的 GC,gc 会大量占用 ui 线程和 cpu 资源,会导致 app 整体卡顿。


避免发生内存抖动的几点建议:


  • 尽量避免在循环体内创建对象,应该把对象创建移到循环体外。

  • 注意自定义 View 的 onDraw()方法会被频繁调用,所以在这里面不应该频繁的创建对象。

  • 当需要大量使用 Bitmap 的时候,试着把它们缓存在数组或容器中实现复用。

  • 对于能够复用的对象


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


,同理可以使用对象池将它们缓存起来。


13.Android 中 ClassLoader 的种类 &特点:


=============================


  • BootClassLoader(Java 的 BootStrap ClassLoader):


用于加载 Android Framework 层 class 文件。


  • PathClassLoader(Java 的 App ClassLoader):


只能加载已经安装过的 apk 的 dex 文件


  • DexClassLoader(Java 的 Custom ClassLoader):


可以从一个 jar 包或者未安装的 apk 中加载 dex 文件


  • BaseDexClassLoader:


是 PathClassLoader 和 DexClassLoader 的父类。


14.SharePreference 为什么不能存储较大 value


================================


public String getString(String key, @Nullable String defValue) {


synchronized (this) {


awaitLoadedLocked();


String v = (String)mMap.get(key);


return v != null ? v : defValue;


}


}


private void awaitLoadedLocked() {


while (!mLoaded) {


try {


wait();


} catch (InterruptedException unused) {


}


}


  • SharePreference 存值的时候,内部会有一个静态的 map 保存了你所有的 key 和 value


private ArrayMap<File, SharedPreferencesImpl> getSharedPreferencesCacheLocked() {


if (sSharedPrefsCache == null) {


sSharedPrefsCache = new ArrayMap<>();


}


final String packageName = getPackageName();


ArrayMap<File, SharedPreferencesImpl> packagePrefs = sSharedPrefsCache.get(packageName);


if (packagePrefs == null) {


packagePrefs = new ArrayMap<>();


sSharedPrefsCache.put(packageName, packagePrefs);


}


return packagePrefs;


}


15.实现 View 滑动的几个办法


================


  • View 自身提供的 scrollTo()和 scrollBy 方法。但只适合对 View 内容的滑动

  • 使用动画。但滑动后的 View 点击没有效果,所以适用于没有交互的 View

  • 改变布局参数,比如 layoutParams.left。比动画稍微复杂,适合有交互的 View


Scroller 使用。调用 startScroll 方法,然后 invidate() --> View 会调用 onDraw(),里面会调用 computeScroll(),此方法默认空实现,需要自行实现 --> 重写 computeScroll(),实现滑动,如果没有结束,postInvalidate()重绘



16.事件分发


=======








  • 源码


// 1. Activity 的 dispatchTouchEvent()方法


public boolean dispatchTouchEvent(MotionEvent ev) {


if (ev.getAction() == MotionEvent.ACTION_DOWN) {


onUserInteraction();


}


//交给 PhoneWindow 处理


if (getWindow().superDispatchTouchEvent(ev)) {


return true;


}


return onTouchEvent(ev);


}


// 2. PhoneWindow 的 superDispatchTouchEvent()方法


public boolean superDispatchTouchEvent(MotionEvent event) {


//交给 DecorView 处理


return mDecor.superDispatchTouchEvent(event);


}


// 3. 由于 DecorView 是 FrameLayout 子类,所以事件会被传递到 DecorView 的子 View 也就是,setContentView 设置的 View 中


  • View 的事件分发




17.View 的测量


==========




用户头像

Android架构

关注

还未添加个人签名 2021.10.31 加入

还未添加个人简介

评论

发布
暂无评论
Android面试主题整理合集(一),android开发前景