妥妥的去面试之Android基础(四)

笔者由于在近期需要找工作,所以近期最主要的任务就是准备面试,不打无准备之仗。只有你准备充分了,那么你想得到的机会才可能有机会入你怀中。

笔者会将准备面试的学习过程记录下来,方便自己复盘的同时也希望能给一道找工作的小伙伴们一些帮助。笔者准备的内容大纲如下

Android面试大纲.png

妥妥的去面试之Android基础(一)

妥妥的去面试之Android基础(二)

妥妥的去面试之Android基础(三)

接下来开始本篇博客的正菜:

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传递数据为什么需要序列化?

序列化,表示将一个对象转换成可存储或可传输的状态。

需要序列化的原因有三种情况:

  1. 永久性保存对象,将对象的字节序列存储到本地文件中;
  2. 对象在网络中传递
  3. 对象在IPC间传递

推荐阅读更多精彩内容