Android8.0 Service
今天照着书上和博客的教程去学习,结果发现各种报错(如下图)。就知道service在高版本Android中又有了新的规则,于是将今天的学习整理成笔记,方便日后复习。不过Android的每次更新,都一直在努力收紧应用权限。不过我觉得挺好的,开放的权限导致了很多安全问题和性能问题,权限上去了用户体验会好很多。
生命周期
从上图可看到有两种方法可以启动Service,下面分别介绍:
第一种:其他组件调用Context的**startService()方法可以启动一个Service,并回调服务中的onStartCommand()。如果该服务之前还没创建,那么回调的顺序是onCreate()->onStartCommand()。服务启动了之后会一直保持运行状态,直到stopService()或stopSelf()**方法被调用,服务停止并回调onDestroy()。
第二种:其它组件调用Context的**bindService()可以绑定一个Service,并回调服务中的onBind()方法。类似地,如果该服务之前还没创建,那么回调的顺序是onCreate()->onBind()。之后,调用方可以获取到onBind()方法里返回的IBinder对象的实例,从而实现和服务进行通信。只要调用方和服务之间的连接没有断开,服务就会一直保持运行状态,直到调用了unbindService()**方法服务会停止,回调顺序onUnBind()->onDestroy()。
注意,这两种启动方法并不冲突,当使用startService()启动Service之后,还可再使用bindService()绑定,只不过需要同时调用 stopService()和 unbindService()方法才能让服务销毁掉。
普通服务
-
建立自己的服务类My Service继承Service,此服务的优先级比较低,可能会被回收。
-
在配置文件中进行注册。四大组件除了广播接收器可用动态注册,定义好组件之后都要在配置文件注册。
-
活动中利用Intent可实现Service的启动,代码如下:
Intent intent = new Intent(this, MyService.class); startService(intent); //开启服务 stopService(intent); //停止服务
前台服务
前台服务可以保证一直运行
QQ是个什么鬼,8.0以上将应用清理后还能接收消息???静态广播又没了,你还可以这样的吗?
刚刚查了一下文档,个人猜测是因为QQ拥有特殊的广播权限。或者说拿到了其他权限。
前台服务的写法有所不同,通过startForegroundService(intent)启动后,还得在5秒之内开启通知栏的提示,不然直接闪退。
@Override
public void onCreate() {
super.onCreate();
Log.i(TAG, "onCreate: ");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
//适配安卓8.0
String channelId = getChannelId() + "";
String channelName = "ok";
NotificationChannel channel = new NotificationChannel(channelId, channelName,
NotificationManager.IMPORTANCE_MIN);
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
manager.createNotificationChannel(channel);
startForeground(getChannelId(), getNotification());
}
}
protected Notification getNotification(String content) {
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, getChannelId() + "");
if (TextUtils.isEmpty(content)) {
return builder.build();
}
builder.setContentTitle(getString(R.string.app_name))
.setContentText(content)
.setWhen(System.currentTimeMillis())
.setSmallIcon(R.mipmap.ic_launcher)
.build();
return builder.build();
}