前言
在官方文档 Android 8.0之后的行为变更 中有这样一段话:
Android 8.0 有一项复杂功能;系统不允许后台应用创建后台服务。 因此,Android 8.0 引入了一种全新的方法,即 Context.startForegroundService(),以在前台启动新服务。startService 和startForegroundService 最终调用调用的接口时一样的,只是其中要求foreground 启动service。
服务的创建
创建服务并重写onCreat()方法,在方法中实现通知栏代码,启动服务后五秒内未找到服务中的startForeground()方法则应用进入ANR。startForeground()方法中的id不能为null或0。
public class MyService extends Service {
public MyService() {
}
@Override
public void onCreate() {
super.onCreate();
Log.d("gaoqiang", "onCreate: ");
/**
* Oreo不用Priority了,用importance
* IMPORTANCE_NONE 关闭通知
* IMPORTANCE_MIN 开启通知,不会弹出,但没有提示音,状态栏中无显示
* IMPORTANCE_LOW 开启通知,不会弹出,不发出提示音,状态栏中显示
* IMPORTANCE_DEFAULT 开启通知,不会弹出,发出提示音,状态栏中显示
* IMPORTANCE_HIGH 开启通知,会弹出,发出提示音,状态栏中显示
*/
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
NotificationCompat.Builder builder ;
String CHANNEL_ID = "my_channel_01";
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){ //Android 8.0适配
NotificationChannel channel = new NotificationChannel(CHANNEL_ID,
"Channel human readable title",
NotificationManager.IMPORTANCE_DEFAULT);//如果这里用IMPORTANCE_NOENE就需要在系统的设置里面开启渠道, //通知才能正常弹出
manager.createNotificationChannel(channel);
builder = new NotificationCompat.Builder(this,String.valueOf(CHANNEL_ID));
}else{
builder = new NotificationCompat.Builder(this);
}
builder.setContentTitle("this is content title") //指定通知栏的标题内容
.setContentText("this is content text") //通知的正文内容
.setWhen(System.currentTimeMillis()) //通知创建的时间
.setSmallIcon(R.drawable.ic_launcher_background) //通知显示的小图标,只能用alpha图层的图片进行设置
.setLargeIcon(BitmapFactory.decodeResource(getResources(),R.drawable.ic_launcher_background));
Notification notification = builder.build() ;
startForeground(1, notification);
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
}
主活动启动前台服务
public class MainActivity extends AppCompatActivity {
private TextView mTvContent;
private Button mBtChange;
private Observable observable;
private Observer<String> observer;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initUi();
Intent intent = new Intent(this,MyService.class);
mBtChange.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
startService(intent);
}
});
}
private void initUi() {
mBtChange = findViewById(R.id.bt_change);
mTvContent = findViewById(R.id.tv_content);
}
}
android 9.0之后需要加入权限
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
android 8.0之后对后台服务进行限制那么如何解决后台Service限制呢?
官方建议使用JobScheduler替换后台Service,官方还举了一个例子,有一个图库app需要检测当前用户是否收到了来自朋友分享的图片,即使app没有运行于前台。在Android 8.0之前,可以使用后台Service来检测应用的云存储,但是这有一个问题,这个Service一起在后台运行,它会消耗资源,影响手机性能。但是从Android 8.0,使用JobScheduler替换后台Service,它会周期性启动一个任务,查询服务器,然后退出。相比于后台Service,它消耗的资源明显较少,间接提升了手机性能。
————————————————
版权声明:本文为优快云博主「weixin_39977136」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.youkuaiyun.com/weixin_39977136/article/details/113042375