@ZeroGeek
2018-08-03T07:51:20.000000Z
字数 4012
阅读 711
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
@Override
public 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;
@Override
protected void onStart() {
super.onStart();
// 注意这里
Intent intent = new Intent(this, LocalService.class);
bindService(intent, mConnection, Service.BIND_AUTO_CREATE);
}
@Override
protected void onStop() {
super.onStop();
if (mBound) {
unbindService(mConnection);
mBound = false;
}
}
// 所有与Service的连接都是通过ServiceConnection
private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
LocalService.LocalBinder binder = (LocalService.LocalBinder) service;
mService = binder.getService();
mBound = true;
}
@Override
public void onServiceDisconnected(ComponentName name) {
mBound = false;
}
};
之后可以用mService去处理任务了。别忘了声明Service。
public class MessengerService extends Service {
static final int MSG_SAY_HELLO = 1;
class IncomingHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_SAY_HELLO:
// do something
break;
default:
super.handleMessage(msg);
}
}
}
final Messenger mMessenger = new Messenger(new IncomingHandler());
@Override
public 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' value
Message msg = Message.obtain(null, MessengerService.MSG_SAY_HELLO, 0, 0);
try {
mService.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
protected void onStart() {
super.onStart();
bindService(new Intent(this, MessengerService.class), mConnection,
Context.BIND_AUTO_CREATE);
}
@Override
protected 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.