Android面试知识

参考文章

  1. 备战2022,Android中高级面试必知必会
  2. 《Android 源码设计模式解析与实战 第2版》

2 assets和res/raw的区别

  1. assets中的文件资源不会映射到R中,而res中的文件都会映射到R中,所以raw文件夹下的资源都有对应的ID;
  2. assets可以能有更深的目录结构,而res/raw里面只能有一层目录;
  3. 资源存取方式不同,assets中利用AssetsManager,而res/raw直接利用getResource(), openRawResource(R.raw.fileName)

3 Serializable 和 Parcelable 的区别

  1. Serializable 使用 I/O 读写存储在硬盘上,而 Parcelable 是直接在内存中读写。很明显,内存的读写速度通常大于 IO读写,所以在 Android 中传递数据优先选择 Parcelable。
  2. Serializable 会使用反射,序列化和反序列化过程需要大量 I/O 操作; Parcelable 自已实现封送和解封(marshalled &unmarshalled)操作不需要用反射,数据也存放在Native内存中,效率要快很多。

传递大数据的方式

文件,数据库,静态变量

Context的理解

是运行上下文环境。代码角度看是Application、Activity、Service。
所有Context都是在主线程ActivityThread创建

导致内存泄露:
2 1. 静态资源
2. 单例模式
避免:

  1. 尽量少用Context对象获取静态变量,静态方法,以及单例对象
  2. 在引用静态资源,创建静态方法,单例等情况下,使用生命周期更长的Application的Context去创建UI相关的对象,如Dialog,View等。

Activity

Activity与Fragment

  1. Activity、View、Window的关系?

    Activity -》 PhoneWindow -》DecorView -》 ActionBar&ContentView
    DecorView是一个FrameLayout

  2. Activity1跳转到Activity2,Activity2显示缓慢的原因?

    • 在Activity1的onPause()有耗时操作;
    • 在Activity2的onCreate()或者onStart()onResume()中有耗时操作;
      总结 在Activity2的onResume及之前有耗时操作(以上的4个方法过程,均在Activity2的onResume()之前执行)

4 Service

  1. startService和 bindService的区别
    • startService: 与调用者无关, 调用者退出, service不会关闭;
      生命周期:onCreate-onStartCommand -- onDestroy
    • bindService: 与调用者绑定, 调用者关闭, service会关闭 (activity在finish的时候, 会直接调用service进入销毁周期);
      生命周期:onCreate-onBind -- onUnbind-onDestroy
  2. IntentService
    • IntentService继承自Service,可用 startService() 启动,也需要在 AndroidManifest.xml 中注册
    • 可多次启动同一个IntentService,它们会自一个接一个地排队处理
    • 可以执行耗时任务, 在onHandleIntent()中执行
    • 操作完成时,不用手动停止IntentService,它会自动判定停止, 多次startService, 只会执行一次onDestroy

* Handler机制

Handler发送Message到MessageQueue中, Looper从MessageQueue中取出Message,交给Handler的handleMessage方法进行处理

Handler:负责消息的发送和处理
Message:消息对象(类似于链表的一个节点)
MessageQueue:消息队列,用于存放消息对象的数据结构
Looper:消息队列的矗立着,用于轮询消息队列的消息对象

5.1 子线程能否直接new一个Handler?

不能直接new,因为在Handler的构造方法中,会通过Looper.myLooper()获取mLooper对象,子线程中mLooper对象为空,会抛异常。
如果是创建子线程的Handler, 需要三步:
1. Looper.prepare(); //为当前线程准备消息队列
2. Handler handler = new Handler(); // 默认构造方法跟当前线程中的Looper产生关联
3. Looper.loop(); //开启循环取消息
因为子线程的handler需要准备looper,同时要启动Looper.loop(),只有这样handler的机制才能够正常运行。

5.2 一个线程可以有几个Handler,几个Looper,几个MessageQueue对象?

无数个Handler,一个Looper,一个MessageQueue

在Looper.prepare()中,创建了Looper对象,并放入ThreadLocal中,通过ThreadLocal获取Looper对象,ThreadLocal内部维护了一个ThreadLocalMap,其是以当前thread作为key的,所以可以看出一个thread最多只有一个looper对象;在Looper的构造方法中,会创建MessageQueue对象,因为Looper只会构造一个,所以MessageQueue对象只有一个。

5.3 Hand

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值