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

作者: 树獭非懒 | 来源:发表于2019-02-21 21:53 被阅读15次

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

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

    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间传递

    相关文章

      网友评论

        本文标题:妥妥的去面试之Android基础(四)

        本文链接:https://www.haomeiwen.com/subject/ydkjyqtx.html