服务(Service)
服务是Android中实现程序后台运行的解决方案,非常适合去执行那些不需要和用户交互而且还要求长期运行的任务。服务的运行不依赖与任何用户界面,即使程序被切换到后台,或者用户打开了另外一个应用程序,服务仍然能够保持正常运行。
PS:服务不是运行在一个独立的进程当中,而是依赖于创建服务时所在的应用程序进程。当某个应用程序进程被杀掉时,所有依赖于该进程的服务也会停止运行。
服务并不会自动开启线程,所有的代码都是默认运行在主线程当中的。因此需要在服务的内部手动创建子线程,并在这里执行具体的任务,否则就有可能出现主线程被阻塞住的情况。
Android多线程编程
线程的基本用法:
new Thread(newRunnable(){
@Override
public void run(){
//处理具体的逻辑
}
}).Start();
不能在子线程中更新UI:
Android的UI也是线程不安全的,如果想要更新应用程序里的UI元素,则必须在主线程中进行,否则就会出现异常。
异步消息处理机制
Android中的异步消息处理主要由4个部分组成:
Message Handle MessageQueue Looper
Message:
Message是在线程之间传递的消息,可以在内部携带少量的信息,用于在不同线程之间交换数据。
Handle:
主要用于发送和处理消息;
发送消息一般是使用Handle的sendMessage()方法,而发出的消息经过一系列地辗转处理后,最终会传递到Handle的handleMessage()方法中。
MessageQueue
消息队列,主要用于存放所有通过Handle发送的消息。这部分消息会一直存在于消息队列中,等待被处理。每个线程中只会有一个MessageQueue对象。
Looper
Looper是每个线程中的MessageQueue的管家。每个线程中也会有一个Looper对象。
异步消息处理的流程:
首先,需要在主线程当中创建一个Handle对象,并重写handleMessage()方法。
然后,当子线程中需要进行UI操作时,就创建一个Message对象,并通过Handle将这条消息发送出去。
之后在这条消息会被添加到MessageQueue的队列中等待被处理,而Looper则会一直尝试从MessageQueue中取出待处理消息,最后分发回Handle的handleMessage()方法中。
PS:runOnUiThread()方法就是一个异步消息处理机制的接口封装。
使用AsyncTask
(实现原理也是基于异步消息处理机制)AsyncTask是一个抽象类,必须要创建一个子类去继承它。
3个泛型参数:
Params: 在执行AsyncTask时需要传入的参数,可用于在后台任务中使用。
Progress:后台任务执行时,如果需要在界面上显示当前的进度,则使用这里指定的泛型作为返回值类型。
Result:当任务执行完毕后,如果需要对结果进行返回,则使用这里指定的泛型作为返回值类型。
AsyncTask的方法:
1.onPreExecute()
在后台任务开始执行之前调用,用于进行一些界面上的初始化操作,比如显示一个进度条对话框。
2.doInBackground(Params...)
这个方法中的所有代码都会在子线程中运行,在这里处理所有耗时任务。任务一旦完成就可以通过return语句来将任务的执行结果返回。在这个方法中不可以进行UI操作。(如需更新UI元素,可调用publishProgress(Progress...))
3.onProgressUpdate(Progress...)
当在后台任务中调用了publishProgress(Progress...)后,该方法就会很快被调用。可以对UI进行操作,利用参数的数值就可以对界面元素进行相应的更新。
4.onPostExecute(Result)
当后台任务执行完毕并通过return语句进行返回时,这个方法就很快会被调用。
PS:使用AsyncTask的诀窍就是,在doInBackground()方法中执行具体耗时任务,在onProgressUpdate()方法中进行UI操作,在onPostExecute()方法中执行一些任务的收尾工作。
从子线程切换到UI线程:publishProgress()方法
- 启动服务:startService(Intent)
- 停止服务:StopService(Intent)||stopSelf()
- 绑定服务:bindService(Intent,connection,BIND_AUTO_CREATE)
- 解绑服务:unbindService(connection)
- 同时调用startService()和bindService()时,要同时调用stopService()和unbindService()方法,onDestroy()才会执行。
前台服务:startForeground()
IntentService: 集开启线程和自动停止于一身。
onHandleIntent(Intent intent):该方法在子线程中运行。