Android 常见面试题详细解答(一)

“ 金三银四,又是一年跳槽季,关注我也许面试中你遇到的难题在这里有你想要的解答。”

1.什么是Activity

  Activity是四大组件之一,其他三大组件:service、BroadcastReceiver、ContentProvider;

2.Activity的生命周期

  onCreate()——》onStart()——》onResume()——》onPause()——》onStop()(——》onRestart()——》onStart())——》onDestroy()

3.Service两种启动方式

  startService():onCreate()——》onStartCommand()——》Running Service——》onDestroy()
  bindService():onCreate()——》onBind()——》Running Service——》onUnBind()——》onDestroy()
  同一个Service可以在不同Activity中执行,但只有一个Service实例,由于Service运行在主线程上所以Service不能直接做耗时操作可创建子线程来做耗时操作;
  startService()和bindService()混合启动时只会创建一个Service,所以只会走一次onCreate()方法,多次调用startService()时会多次执行onStartCommand()方法,但是多次bindService()时onBind()方法只会执行一次,如果想要执行多次onBind()方法需要intent.setType(type),给intent值传入不同type就会认为intent不同然后再次执行onBind()方法,关闭Service的时候也要注意由于两种启动方式都执行了想要彻底关闭需要执行unbindService()和stopService(),单一执行任何一个都无法关闭Service;

4.BroadcastReceiver

  BroadcastReceiver普通广播,广播发送方式:sendBroadcast()发送无序广播;
sendOrderBroadcast(intent,“string”)发送有序广播;sendStickyBroadcast()发送粘滞广播一直滞留等待下次注册广播依然能够接收此广播需要注册权限;
  LocalBroadcastManager本地广播:只能传输在App内部,不会被其他App接收,确保数据安全;接收不到其他App广播,免干扰;比BrocastReceiver更加高效。

5.ContentProvider

  ContentProvider不同应用数据共享提供增、删、改、查。

6.Android六大进程分类
  1. 前台进程——》可见和正在用户交互的Activity、service、广播;
  2. 可见进程——》能被看见但是没有用户交互;
  3. 服务进程——》音乐播放进程、网络下载进程;
  4. 后台进程——》Activity不可见调了onStop()方法的;
  5. 空进程——》应用back退回桌面时保留空进程作为缓存减少组件初始化时间,提高线程启动速度;

  Android进程间不能直接通信需要借助Binder通信,当然要想实现Binder通信还需要通过AIDL和service实现Binder通信;

7.线程

  线程是CPU调度的基本单位,是一个程序能够独立运行的最小单元。作为Android开发者说到线程值得一提的是现在很多误导把Android的Handler跟线程混为一谈十分令人气愤的是还有人说用Handler能实现多线程,我就想知道Handler就是一个处理消息的一种机制跟多线程有毛线关系啊,如果非要说Handler跟线程有关系那也只是能够用来处理线程消息(比如:在子线程中拿到UI程的Handler对象发送消息然后UI线程的Handler拿到消息就可以刷新UI了)也就这半毛钱的关系,以后考官再问线程时千万不要再说用Handler能够实现什么多线程,不了解Handler的可以先去了解一下Android开发 面试必问的Handler消息机制,这里就不多讲了,还是回来说咱们的线程吧。

  先来说说线程的五种状态:
  1. 新建状态(New): 线程对象被创建后,就进入了新建状态。
  2. 就绪状态(Runnable): 也被称为“可执行状态”,线程对象被创建后,其它线程调用了该对象的start()方法时线程进入就绪状态,处于就绪状态的线程,随时可能被CPU调度执行。
  3. 运行状态(Running): CPU发送调度指令,线程获得权限进行执行,注意线程只能从就绪状态进入到运行状态。
  4. 阻塞状态(Blocked): 阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行,直到线程进入就绪状态,才有机会转到运行状态。阻塞的情况分三种:
    1. 等待阻塞 – 通过调用线程的wait()方法,让线程等待某工作的完成。
    2. 同步阻塞 – 线程在获取synchronized同步锁失败(因为锁被其它线程所占用),它会进入同步阻塞状态。
    3. 其他阻塞 – 通过调用线程的sleep()或join()或发出了I/O请求时,线程会进入阻塞状态。当sleep()完成时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。
  5. 死亡状态(Dead): 线程执行完毕或者因为异常退出了run()方法,该线程结束生命周期。
8.多线程

  多线程时频繁创建线程会造成内存过度消耗引起OOM,频繁切换线程会造成CPU过度使用引起卡顿、手机发烫,频繁销毁线程会因为过度gc造成内存抖动引起卡顿、性能降低,所以为了解决这一系列问题防止性能急剧下降,我们就需要使用线程池来减少线程对象的创建、切换、销毁,从而减少性能的消耗。

  Executors类提供了4种不同的线程池:
  1. NewCachedThreadPool:适合大量且耗时短任务;无效扩大的缓存线程池,空闲线程可缓存60s后就会被杀死回收,只要有请求就必须要找到一条工作线程来处理,如果当前没有空闲线程就会重新创建一个新的线程。
  2. NewFixedThreadPool:适合固定数量且耗时较长任务;固定大小线程池,核心线程数和最大线程数都为用户设定线程数,超出固定线程为空闲线程时立即回收,超出固定线程为任务线程时则存放到阻塞队列中等待线程是否后按顺序执行。
  3. NewSingleThreadPool:适合按顺序执行任务,跟NewFixedThreadPool类似不同的就是固定线程数只有一条工作线程,超出任务线程数固定线程数责放到阻塞队列排队输出执行。
  4. NewScheduleThreadPool:适合周期循环执行任务,可设置循环固定线程数、首次延迟时间、循环时间。

长按二维码关注!你的每个赞和在看,我都喜欢!Android 常见面试题详细解答(一)_第1张图片

你可能感兴趣的