Android学习之路——7.Service
这两天又学习了Android四大组件之一的Service。
继续分享我的学习历程。(*^__^*) 嘻嘻
(一)注意的细节:
(1)Service不是一个单独的Process,除非特别指派了,也不是一个Thread,但也不是运行在Main Thread中。
(2)Service的使用有两个目的,一是告诉系统要后台执行程序,一般是用Context.startService()来开启Service的(注意即使开启Service的Activity什么的destroy了,Service还是存在的,直到Context.stopService()或stopSelf()的调用),二是向其他的类,进程提供功能,这个一般是Context.bindService()来开启Service。
(3)Service的生命周期:
调用的Context.startService() oncreate() --> onStartCommand ()--> Service is running --> The service is stopped by its or a client--> onDestroy() --> Service is shut down
调用Context.bindService() onBind() --> Service is running(clients are bound to it) --> All client unbind by calling unbindService() -->onUnbind() --> onDestroy()
在Service生命周期中要注意的有:
①不管调用几次Context.startService(),即使这样导致多次调用onStartCommand(),但是一旦调用了Context.stopService() 或者stopSelf() ,这个Service就会停止。
②onStartCommand()返回一个int值,在Service类里有定义,比如START_STICKY,START_NOT_STICKY,START_REDELIVER_INTENT。
③onBind()需要返回一个IBinder对象,以便Context和Service交互
④当Service因为系统内存低而被杀死后,系统会重启去启动它
⑤当一个有连接到Service的Context要销毁时,要调用unbindService(ServiceConnection)来断开连接
(4)当一个Service运行在前台时,必须为状态栏提供一个notification,并且这个notification一直存在直到这个Service停止或转移到后台。要让一个Service运行在前台,只要调用startForeground()方法,这个方法有两个参数,一个是唯一的标识,另一个是Notification,比如:
Notification notification = new Notification(R.drawable.icon, getText(R.string.ticker_text), System.currentTimeMillis());Intent notificationIntent = new Intent(this, ExampleActivity.class);PendingIntent pendingIntent = PendingIntent.getActivity(this,0,notificationIntent, 0);notification.setLatestEventInfo(this, getText(R.string.notification_title),getText(R.string.notification_message), pendingIntent);startForeground(ONGOING_NOTIFICATION, notification);(从前台移除只要调用stopForeground()方法,这个方法有一个boolean参数,表示是否移除notification。
protected class BoundBinder extends Binder {/** * 返回当前Service实例,将公有方法暴露给客户端,当然也可以是其他对象 * * @return Service实例 */BoundService getService() {return BoundService.this;}} /** * @see android.app.Service#onBind(android.content.Intent) */@Overridepublic IBinder onBind(Intent intent) {Log.i(TAG, TAG + " onBind");return mBind;}private class Connection1 implements ServiceConnection {@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {BoundBinder binder = (BoundBinder) service;boundService = binder.getService();//这个方法在BoundBinder类中实现mText.setText(boundService.getText());// BoundService暴露给客户端的方法stopService(boundIntent);// 停止服务unbindService(connection1);// 断开连接,记得加这句话}@Overridepublic void onServiceDisconnected(ComponentName name) {Log.i(TAG, TAG + " Contact1 onServiceDisconnected");}} /** * bind to a service * * @param v */ public void bound(View v) {connection1 = new Connection1();boundIntent = new Intent(this, BoundService.class);bindService(boundIntent, connection1, BIND_AUTO_CREATE); } /** * 当客户端的Messenger发来Message则用这个Handler处理 这里简单的打印一句话。 * 然后通过Message绑定的Messenger对象再给客服端发送一个消息 */private Handler mHandler = new Handler() {/** * @see android.os.Handler#handleMessage(android.os.Message) */@Overridepublic void handleMessage(Message msg) {Log.i(TAG, TAG + " Handler handlemessage");Messenger m = msg.replyTo;try {m.send(Message.obtain());} catch (RemoteException e) {e.printStackTrace();}}}; private Messenger mMessenger = new Messenger(mHandler); /** * @see android.app.Service#onBind(android.content.Intent) */@Overridepublic IBinder onBind(Intent intent) {Log.i(TAG, TAG + " onBind");return mMessenger.getBinder();} private class Connection2 implements ServiceConnection {/** * 向MessengerService发送一个Message,这个Message中含有当前类中的一个Messenger实例,方便MessengerService和这个类通信 * * @see android.content.ServiceConnection#onServiceConnected(android.content.ComponentName,android.os.IBinder) */@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {messenger = new Messenger(service);Message message = Message.obtain();message.replyTo = mMessenger;// 将Message的replyTo绑定到客户端定义的Messenger,以便于MessengerService向客户端发送信息try {messenger.send(message);} catch (RemoteException e) {e.printStackTrace();}}@Overridepublic void onServiceDisconnected(ComponentName name) {Log.i(TAG, TAG + " Contact2 onServiceDisconnected");}} private Handler mHandler = new Handler() {/** * 处理从MessengerService返回的Message,提示服务,断开连接 * * @see android.os.Handler#handleMessage(android.os.Message) */@Overridepublic void handleMessage(Message msg) {Log.i(TAG, TAG + " Handler handleMessage");stopService(messengerIntent);unbindService(connection2);}};/** * 用于MessengerService向Handler发送Message的Messenger */private Messenger mMessenger = new Messenger(mHandler);public class HelloIntentService extends IntentService {/** * A constructor is required, and must call the super IntentService(String) * constructor with a name for the worker thread. */public HelloIntentService() {super("HelloIntentService");}/** * The IntentService calls this method from the default worker thread with * the intent that started the service. When this method returns, * IntentService stops the service, as appropriate. */@Overrideprotected void onHandleIntent(Intent intent) {// Normally we would do some work here, like download a file.// For our sample, we just sleep for 5 seconds.long endTime = System.currentTimeMillis() + 5 * 1000;while (System.currentTimeMillis() < endTime) {synchronized (this) {try {wait(endTime - System.currentTimeMillis());} catch (Exception e) {}}}}}

