1、Service 生命周期

2、Service 分类
- 按功能分类
| 类别 | 特点 |
|---|
| 不可通信后台服务 | 1.startService 启动。2.调用者退出能存在 |
| 可通信后台服务 | 1.bindService 启动。2.随调用者的销毁而销毁 |
- 按运行类型分类
| 类别 | 特点 |
|---|
| 前台服务 | 1.通知栏显示。2.优先级更高,不会因内存不足被回收 |
| 后台服务 | 1.后台运行。2.内存不足会被回收 |
- 按运行地点分类
| 类别 | 特点 |
|---|
| 本地服务 | 1.运行在主线程。2.主线程终止,服务也会终止 |
| 远程服务 | 1.运行在独立线程。2.服务常驻后台,不受 Activity 影响 |
3、Service 应用
public class ServiceActivity extends AppCompatActivity implements View.OnClickListener{
private MyService.MyBinder binder;
private Intent intent;
private MyServiceConnection conn = new MyServiceConnection();
private boolean isConnected = false;
private class MyServiceConnection implements ServiceConnection{
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
binder = (MyService.MyBinder)service;
}
@Override
public void onServiceDisconnected(ComponentName name) {
binder = null;
}
}
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_service);
findViewById(R.id.btn_startService).setOnClickListener(this);
findViewById(R.id.btn_bindService).setOnClickListener(this);
findViewById(R.id.btn_stopService).setOnClickListener(this);
findViewById(R.id.btn_unbindService).setOnClickListener(this);
findViewById(R.id.stopForeground).setOnClickListener(this);
intent = new Intent(this,MyService.class);
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.btn_startService:
startService(intent);
break;
case R.id.btn_bindService:
isConnected = bindService(intent,conn, Context.BIND_AUTO_CREATE);
break;
case R.id.btn_stopService:
stopService(intent);
break;
case R.id.btn_unbindService:
if(isConnected){
unbindService(conn);
isConnected = false;
}
break;
case R.id.stopForeground:
if(binder!=null){
binder.getService().stopForeground();
}
break;
}
}
}
public class MyService extends Service {
private MyBinder binder = new MyBinder();
@Override
public void onCreate() {
super.onCreate();
Log.e("tag","onCreate");
// 后台服务转前台服务
sendSimpleNotification(this);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e("tag","onStartCommand");
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
Log.e("tag","onDestroy");
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
Log.e("tag","onBind");
return binder;
}
@Override
public boolean onUnbind(Intent intent) {
Log.e("tag","onUnbind");
return super.onUnbind(intent);
}
public class MyBinder extends Binder{
public MyService getService() {
return MyService.this;
}
}
public void sendSimpleNotification(Context context) {
int id = 1000;
String groupId = "groupId_1";
String groupName = "渠道组名1";
String channelId = "channelId_1";
String channelName = "渠道名1";
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, channelId);
builder.setContentTitle("简单的通知的标题")
.setContentText("这是通知内容")
.setLargeIcon(BitmapFactory.decodeResource(
context.getResources(),
R.mipmap.ic_launcher))
.setAutoCancel(true)// 自己维护通知的消失
.setSmallIcon(R.mipmap.ic_launcher)
.setPriority(NotificationCompat.PRIORITY_HIGH);
//构建一个Intent
Intent resultIntent = new Intent( context,MainActivity.class);
// 封装一个Intent
PendingIntent resultPendingIntent = PendingIntent.getActivity(
context, 0, resultIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
builder.setContentIntent(resultPendingIntent);
// 这里必须设置chanenelId,要不然该通知在8.0手机上,不能正常显示
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
createChannelId(context,groupId,groupName,channelId,channelName);
builder.setChannelId(channelId);
}
// 让Service变成前台Service,并在系统的状态栏显示
startForeground(id, builder.build());
// NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
// notificationManager.notify(id, builder.build());
}
@RequiresApi(Build.VERSION_CODES.O)
public static void createChannelId(Context context,String groupId,String groupName , String channelId,String channelName){
// 分组(可选)groupId 要唯一
NotificationChannelGroup ncp1 = new NotificationChannelGroup(groupId, groupName);
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.createNotificationChannelGroup(ncp1);
// channelId 要唯一
NotificationChannel chan = new NotificationChannel(channelId,
channelName,
NotificationManager.IMPORTANCE_DEFAULT);
chan.setLightColor(Color.GREEN);
chan.setGroup(groupId);
// VISIBILITY_PRIVATE:表面只有当没有锁屏的时候才能够显示,VISIBILITY_PUBLIC:表明任何情况下都会显示,VISIBILITY_SECRET:表明在pin,password等安全锁和没有锁屏的情况下才能够显示
chan.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
notificationManager.createNotificationChannel(chan);
}
public void stopForeground(){
stopForeground(true);
}
}