服务是在后台运行,负责更新内容提供器、发出意图、触发通知,它们是执行持续或定时处理的方式。
多线程一般捆绑服务执行任务,因为在activity中开辟多线程执行任务的话,子线程的生命周期得不到保障,可能在应用进入后台时(进入后台后子线程仍会继续执行),activity被释放时同时被释放,而service在进入后台后仍有优先级存在,所以让子线程捆绑它执行,来保障子线程能执行完全。而在servcie的onStartCommand中,不会将一个在主线程运行且消耗长时间的任务放在onStartCommand(虽然进入后台后onStartCommand中的主线程代码仍会继续执行),而子线程的开辟一般就放到onStartCommand。这样onStartCommand就可以快速完成,并返回一个重启行为标识:
START_STICKY:如果service进程被kill掉,保留service的状态为开始状态,但不保留递送的intent对象。随后系统会尝试重新创建service,由于服务状态为开始状态,所以创建服务后一定会调用onStartCommand(Intent,int,int)方法。如果在此期间没有任何启动命令被传递到service,那么参数Intent将为null。
START_NOT_STICKY:“非粘性的”。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统不会自动重启该服务。
START_REDELIVER_INTENT:重传Intent。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统会自动重启该服务,并将Intent的值传入。
START_STICKY_COMPATIBILITY:START_STICKY的兼容版本,但不保证服务被kill后一定能重启。
创建服务
public class MyService extends Service { private final IBinder binder = new MyBinder(); public class MyBinder extends Binder { MyService getService() { return MyService.this; } } @Override public IBinder onBind(Intent intent) { // TODO Auto-generated method stub return null; } @Override public void onCreate() { // TODO Auto-generated method stub super.onCreate(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { //启动一个后台线程来进行处理 if ((flags & START_FLAG_RETRY) == 0) { } else { } // return super.onStartCommand(intent, flags, startId); return Service.START_STICKY; } }
绑定服务
public class MainActivity extends ActionBarActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); startService(new Intent(this, MyService.class)); //绑定服务,这样就可以获取服务对象,从而可以使用服务对象的所有公有方法和属性(应用外的交互可以通过广播意图,或意图中启动服务调度extras Bundle,而AIDL是另一种更紧密的连接方式) Intent bindIntent = new Intent(MainActivity.this, MyService.class); bindService(bindIntent, mConnection, Context.BIND_AUTO_CREATE); } private MyService serviceBinder; private ServiceConnection mConnection = new ServiceConnection() { //处理服务和活动之间的链接 @Override public void onServiceDisconnected(ComponentName name) { //当服务以外对开时调用 serviceBinder = null; } @Override public void onServiceConnected(ComponentName name, IBinder service) { //当建立连接时调用 serviceBinder = ((MyService.MyBinder)service).getService(); } }; }
服务移到前台
public class MyService extends Service { public void moveServiceToForeground() { int NOTIFICATION_ID = 1; Intent intent = new Intent(this, MainActivity.class); PendingIntent pi = PendingIntent.getActivity(this, 1, intent, 0); Notification notification = new Notification(R.drawable.ic_launcher, "Running in the Foreground", System.currentTimeMillis()); notification.setLatestEventInfo(this, "title", "Text", pi); notification.flags = notification.flags | Notification.FLAG_ONGOING_EVENT; startForeground(NOTIFICATION_ID, notification); } }