笔者由于在近期需要找工作,所以近期最主要的任务就是准备面试,不打无准备之仗。只有你准备充分了,那么你想得到的机会才可能有机会入你怀中。
笔者会将准备面试的学习过程记录下来,方便自己复盘的同时也希望能给一道找工作的小伙伴们一些帮助。笔者准备的内容大纲如下
接下来开始本篇博客的正菜:
1.Bitmap使用时需要注意什么?
- 要选择合适的图片规格,因为不同规格的图片所占用的内存不同
ALPHA_8 每个像素占用1byte内存
ARGB_4444 每个像素占用2byte内存
ARGB_8888 每个像素占用4byte内存(默认)
RGB_565 每个像素占用2byte内存
- 图片压缩。通过BitmapFactory对图片进行压缩,这样就会降低内存占用从而在一定程度上避免OOM,提高Bitmap加载时的性能。
- 复用内存。通过软引用(内存不够的时候才会回收掉)来复用内存块,就不需要再重新给这个bitmap申请一块新的内存,避免了一次内存的分配和回收带来的性能消耗。
- 使用recycle()方法及时回收内存,避免内存泄露。
在Android中,Bitmap的存储分为两部分,一部分是Bitmap的数据,一部分是Bitmap的引用。 在Android2.3时代,Bitmap的引用是放在堆中的,而Bitmap的数据部分是放在栈中的,需要用户调用recycle方法手动进行内存回收,而在Android2.3之后,整个Bitmap,包括数据和引用,都放在了堆中,这样,整个Bitmap的回收就全部交给GC了,这个recycle方法就再也不需要使用了。
2.服务有几种启动方式?服务和Activty或服务之间怎么通信?
启动服务两种方式
1.startService
onCreate() --> onStartCommand() --> onDestroy()
- 如果服务已经开启,再次开启的话不会重复的执行onCreate(), 而是会调用onStartCommand()。
- 一旦服务开启后就和开启者没有任何关系了。
- 开启者不能调用服务里面的方法。
2.bindService
onCreate() --> onBind() --> onUnbind() --> onDestroy()
bind的方式开启服务后,如果开启者被销毁了,它也会跟着一起销毁。绑定者可以调用服务里的方法。
3.通信方式
服务和Activity、服务和服务之间可以通过Binder对象、Broadcast(广播)进行通信。
3.Handler为什么会出现内存泄漏,为什么继承Handle就不会出现内存泄漏?
在使用Handler的时候,往往是需要在子线程中做耗时任务的,但是当任务未执行完就把该Handler所在的Activity销毁的话,它是无法被GC的。因为持有非静态内部类的引用是无法被内存回收,所以会出现内存泄露。
解决方法主要在于两点:
- 将Handler声明为静态内部类。因为静态内部类不会持有外部类的引用,所以不会导致外部类实例出现内存泄露。
- 在Handler中添加对外部Activity的弱引用。由于Handler被声明为静态内部类,不再持有外部类对象的引用,导致无法在handleMessage()中操作Activity中的对象,所以需要在Handler中增加一个对Activity的弱引用。
通过继承Handler就可以实现一个Handler静态内部类,还可以在构造方法中添加对外部Activity的弱引用。
public class MainActivity extends Activity {
......
private final MyHandler mHandler = new MyHandler(this);
private static class MyHandler extends Handler {
private final WeakReference<MainActivity> mActivity;
public MyHandler(MainActivity activity) {
this.mActivity = new WeakReference<MainActivity>(activity);
}
@Override
public void handleMessage(Message msg) {
}
}
}
4.在Activity中创建一个thread跟在service中创建一个thread之间的区别?
- 在Activity中被创建:该Thread的就是为这个Activity服务的,完成这个特定的Activity交代的任务,主动通知该Activity一些消息和事件,Activity销毁后,该Thread也没有存活的意义了。
- 在Service中被创建:这是保证最长生命周期的Thread的唯一方式,只要整个Service不退出,Thread就可以一直在后台执行,一般在Service的onCreate()中创建,在onDestroy()中销毁。所以,在Service中创建的Thread,适合长期执行一些独立于APP的后台任务,比较常见的就是:在Service中保持与服务器端的长连接。
5.Bundle传递数据为什么需要序列化?
序列化,表示将一个对象转换成可存储或可传输的状态。
需要序列化的原因有三种情况:
- 永久性保存对象,将对象的字节序列存储到本地文件中;
- 对象在网络中传递;
- 对象在IPC间传递。