@ZeroGeek
2018-08-03T07:51:20.000000Z
字数 4012
阅读 827
Android知识点
Service是一种可以长时间在后台运行任务的应用组件,不提供用户交互。
必须在manifest里面声明service
这个值决定,当系统杀死该Service时,如何继续处理。
START_NOT_STICKY:不重建
START_STICKY:保证Service可重建,适用于媒体播放
START_REDELIVER_INTENT:适用于下载文件
启动Service
Intent intent = new Intent(this, TimeService.class);startService(intent);
创建notification
Intent notificationIntent = new Intent(this, ExampleActivity.class);PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);Notification notification = new Notification.Builder(this).setContentTitle(getText(R.string.notification_title)).setContentText(getText(R.string.notification_message)).setSmallIcon(R.drawable.icon).setContentIntent(pendingIntent).setTicker(getText(R.string.ticker_text)).build();startForeground(ONGOING_NOTIFICATION_ID, notification);
注意:ONGOING_NOTIFICATION_ID一定不能为0.
可通过stopForeground()移出前台任务
看图
提供一种C-S模式,允许进程间通信。
注意:Service可以同时启动和绑定
如果不需要跨进程通信,可以使用继承Binder的方式,得到Service的实例,在Service中提供公有方法给其它组件调用。
简单示例:
public class LocalService extends Service {private final IBinder mBinder = new LocalBinder();@Nullable@Overridepublic IBinder onBind(Intent intent) {return mBinder;}public class LocalBinder extends Binder {LocalService getService () {return LocalService.this;}}// 提供公有方法public void show() {Toast.makeText(getApplicationContext(), "OK!", Toast.LENGTH_SHORT).show();}}
Activity中
private LocalService mService;private boolean mBound;@Overrideprotected void onStart() {super.onStart();// 注意这里Intent intent = new Intent(this, LocalService.class);bindService(intent, mConnection, Service.BIND_AUTO_CREATE);}@Overrideprotected void onStop() {super.onStop();if (mBound) {unbindService(mConnection);mBound = false;}}// 所有与Service的连接都是通过ServiceConnectionprivate ServiceConnection mConnection = new ServiceConnection() {@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {LocalService.LocalBinder binder = (LocalService.LocalBinder) service;mService = binder.getService();mBound = true;}@Overridepublic void onServiceDisconnected(ComponentName name) {mBound = false;}};
之后可以用mService去处理任务了。别忘了声明Service。
public class MessengerService extends Service {static final int MSG_SAY_HELLO = 1;class IncomingHandler extends Handler {@Overridepublic void handleMessage(Message msg) {switch (msg.what) {case MSG_SAY_HELLO:// do somethingbreak;default:super.handleMessage(msg);}}}final Messenger mMessenger = new Messenger(new IncomingHandler());@Overridepublic IBinder onBind(Intent intent) {return mMessenger.getBinder();}}
Messenger mService = null;boolean mBound;private ServiceConnection mConnection = new ServiceConnection() {public void onServiceConnected(ComponentName className, IBinder service) {mService = new Messenger(service);mBound = true;}public void onServiceDisconnected(ComponentName className) {mService = null;mBound = false;}};public void sayHello(View v) {if (!mBound) return;// Create and send a message to the service, using a supported 'what' valueMessage msg = Message.obtain(null, MessengerService.MSG_SAY_HELLO, 0, 0);try {mService.send(msg);} catch (RemoteException e) {e.printStackTrace();}}@Overrideprotected void onStart() {super.onStart();bindService(new Intent(this, MessengerService.class), mConnection,Context.BIND_AUTO_CREATE);}@Overrideprotected void onStop() {super.onStop();if (mBound) {unbindService(mConnection);mBound = false;}}
2种用法都差不多,但是Messenger支持IPC,不支持多线程
Caution: If you use an intent to bind to a Service, ensure that your app is secure by using an explicit intent. Using an implicit intent to start a service is a security hazard because you can't be certain what service will respond to the intent, and the user can't see which service starts. Beginning with Android 5.0 (API level 21), the system throws an exception if you call bindService() with an implicit intent.