Android Service组件在后台不可见,但一般情况下是与其他组件一同运行在一个进程中的(Local Service与其他部分在一个进程,Remote Service单独开进程),而且在主线程中,并不单独启动一个线程(除非程序员自己另外开线程)
Service组件提供了后台执行某些功能以及为其他应用程序提供服务,提供支撑功能的能力。
生命周期:OnCreate()->OnStartCommand()->OnDestroy()。
调用 Context.startService()可以多次调用,但只要调用stopService一次就会stop.多次调用startService或者bindService不会启动多个服务。
local service样例
public class LocalService extends Service { private NotificationManager mNM; // Unique Identification Number for the Notification. // We use it on Notification start, and to cancel it. private int NOTIFICATION = R.string.local_service_started; /** * Class for clients to access. Because we know this service always * runs in the same process as its clients, we don't need to deal with * IPC. */ public class LocalBinder extends Binder { LocalService getService() { return LocalService.this; } } @Override public void onCreate() { mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE); // Display a notification about us starting. We put an icon in the status bar. showNotification(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.i("LocalService", "Received start id " + startId + ": " + intent); // We want this service to continue running until it is explicitly // stopped, so return sticky. return START_STICKY; } @Override public void onDestroy() { // Cancel the persistent notification. mNM.cancel(NOTIFICATION); // Tell the user we stopped. Toast.makeText(this, R.string.local_service_stopped, Toast.LENGTH_SHORT).show(); } @Override public IBinder onBind(Intent intent) { return mBinder; } // This is the object that receives interactions from clients. See // RemoteService for a more complete example. private final IBinder mBinder = new LocalBinder(); /** * Show a notification while this service is running. */ private void showNotification() { // In this sample, we'll use the same text for the ticker and the expanded notification CharSequence text = getText(R.string.local_service_started); // Set the icon, scrolling text and timestamp Notification notification = new Notification(R.drawable.stat_sample, text, System.currentTimeMillis()); // The PendingIntent to launch our activity if the user selects this notification PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, LocalServiceActivities.Controller.class), 0); // Set the info for the views that show in the notification panel. notification.setLatestEventInfo(this, getText(R.string.local_service_label), text, contentIntent); // Send the notification. mNM.notify(NOTIFICATION, notification); } }调用
private LocalService mBoundService; private ServiceConnection mConnection = new ServiceConnection() { public void onServiceConnected(ComponentName className, IBinder service) { // This is called when the connection with the service has been // established, giving us the service object we can use to // interact with the service. Because we have bound to a explicit // service that we know is running in our own process, we can // cast its IBinder to a concrete class and directly access it. mBoundService = ((LocalService.LocalBinder)service).getService(); // Tell the user about this for our demo. Toast.makeText(Binding.this, R.string.local_service_connected, Toast.LENGTH_SHORT).show(); } public void onServiceDisconnected(ComponentName className) { // This is called when the connection with the service has been // unexpectedly disconnected -- that is, its process crashed. // Because it is running in our same process, we should never // see this happen. mBoundService = null; Toast.makeText(Binding.this, R.string.local_service_disconnected, Toast.LENGTH_SHORT).show(); } }; void doBindService() { // Establish a connection with the service. We use an explicit // class name because we want a specific service implementation that // we know will be running in our own process (and thus won't be // supporting component replacement by other applications). bindService(new Intent(Binding.this, LocalService.class), mConnection, Context.BIND_AUTO_CREATE); mIsBound = true; } void doUnbindService() { if (mIsBound) { // Detach our existing connection. unbindService(mConnection); mIsBound = false; } } @Override protected void onDestroy() { super.onDestroy(); doUnbindService(); }在Activity中通过mBoundService调用Service中的public方法来获取后台数据,实际上onServiceConnected中返回的是一个IBinder对象,只不过我们在此已经确定Local Service
已经在执行了,可以进行强制类型转换。
Local Service可以通过发送广播来给前台提供后台数据更新,前台只需要注册一个Receiver既可以与Service通讯。
例子:
后台Service的某个方法进行数据更新后执行
Intent intent = new Intent("XXXX_Message");
sendBroadcast(intent); 通知前台数据已经更新
前台
private MessageReceiver receiver;
class MessageReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context arg0, Intent arg1) {
String action = arg1.getAction();
if (action.equals("XXXX_Message")) {
//从Service接收广播消息
String msgStr = arg1.getStringExtra("msg_str");
}
}
}
@Override
protected void onResume() {
super.onResume();
IntentFilter filter = new IntentFilter("XXXX_Message");
if (receiver == null)
receiver = new MessageReceiver();
//注册BroadcastReceiver
registerReceiver(receiver, filter);
}
@Override
protected void onPause() {
unregisterReceiver(receiver);
super.onPause();
}