1. 服务的概念:服务(Service)是Android中实现程序后台运行的解决方案,它非常适合用于去执行那些不需要和用户交互而且还要求长期运行的任务。依赖于创建服务时所在的应用程序进程。当某个应用程序进程被杀掉时,所有依赖于该进程的服务也会停止运行。
2. 异步消息机制:Android不允许在子线程中进行UI操作的,因为主线程UI是线程不安全的。对于这种情况,Android提供了一套异步消息处理机制,完美地解决了在子线程中进行UI操作的问题。利用在主线程中的Handler中的handleMessage()对消息进行处理。
3. AsyncTask:可以更加方便我们在子线程中对UI进行操作。AsyncTask<Void,Integer, Boolean> {…}AsyncTask的第一个泛型参数指定为Void,表示在执行AsyncTask的时候不需要传入参数给后台任务。第二个泛型参数指定为Integer,表示使用整型数据来作为进度显示单位。第三个泛型参数指定为Boolean,则表示使用布尔型数据来反馈执行结果。经常需要去重写的方法有以下四个:
1) onPreExecute() :会在后台任务开始执行之前调用
2) doInBackground(Params...) :所有代码都会在子线程中运行
3) onProgressUpdate(Progress...) :当在后台任务中调用了publishProgress(Progress...)方法后,这个方法就会很快被调用
4) onPostExecute(Result) :当后台任务执行完毕并通过return语句进行返回时,这个方法就很快会被调用
4. 定义服务:继承Service,重写了onCreate()、onStartCommand()和onDestroy()这三个方法。onCreate()方法是在服务第一次创建的时候调用的,而onStartCommand()方法则在每次启动服务的时候都会调用
5. 活动和服务进行通信:在活动中创建一个ServiceConnection的匿名类,在里面重写了onServiceConnected()方法和onServiceDisconnected()方法。在service中新建一个DownloadBinder类,并让它继承自Binder,接着,在MyService中创建了DownloadBinder的实例,然后在onBind()方法里返回了这个实例。
6. 服务的生命周期:当调用了startService()方法后,又去调用stopService()方法,这时服务中的onDestroy()方法就会执行,表示服务已经销毁了。类似地,当调用了bindService()方法后,又去调用unbindService()方法,onDestroy()方法也会执行。如果服务既调用了startService()方法,又调用了bindService()方法,要同时调用stopService()和unbindService()方法,onDestroy()方法才会执行。
7. 前台服务:如果你希望服务可以一直保持运行状态,而不会由于系统内存不足的原因导致被回收,就可以考虑使用前台服务。前台服务和普通服务最大的区别就在于,它会一直有一个正在运行的图标在系统的状态栏显示。一般使用Nitification实现。
8. 使用IntentService:,服务中的代码都是默认运行在主线程当中的,如果直接在服务里去处理一些耗时的逻辑,就很容易出现ANR(ApplicationNot Responding)的情况。应该在服务的每个具体的方法里开启一个子线程,然后在这里去处理那些耗时的逻辑。只需要在子类中提供一个无参的构造函数,并且必须在其内部调用父类的有参构造函数,然后要在子类中去实现onHandleIntent()这个抽象方法。
《Android疯狂讲义》补充:
Android事件处理
1. 事件监听器(一种委托的事件处理)常见实现形式:内部类(将事件监听器类定义成当前类的内部类),外部类(定义成外部类,不推荐使用),Activity本身作为事件监听器类(让Activity本身实现监听器接口,不推荐使用),匿名内部类(使用匿名内部类创建事件监听对象),直接在布局文件中绑定到标签(该属性的属性值就是一个形如xxx(Viewsource)方法的方法名)。
2. 回调机制中事件源和事件监听器是统一的,所以事件监听器完全消失了,当用户在GUI组件激发某个事件时,组件自己特定的方法将会自己负责处理该事件。事件处理的回调函数返回boolean,表示是否该处理方法已经完全处理该事件。
3. 获取系统的Configuration(getResources().getConfiguration())对象可以设备状态,重写onConfiguration方法响应系统设置更改。
4. 使用handler进行异步消息处理分为两种情况:
1) 在主UI线程中,系统已经初始化了Looper对象,因此程序可以直接创建Handler即可,然后就可以使用Handler发送和处理消息了。
2) 程序员自己启动的子线程,必须自己创建Looper对象,并启动它。创建Looper对象调用prepare()方法即可。(步骤:调用prepare()方法为当前线程创建Looper对象,创建Handler子类实例,重写handleMessage()方法,调用Looper的loop()方法启动Looper)