WorkManager的起源--Service变成鸡肋

根源:Android 8.0以后,谷歌开始收紧Service权限。主要表现的两个方面:

1)服务前台化

不再支持原来单纯的后台服务,启动服务需要前台化启动。

Intent intent = new Intent(context, DownloadCenterService.class);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    context.startForegroundService(intent);
} else {
    // Pre-O behavior.
    context.startService(intent);
}

未切换前台化启动,会出现闪退情况。Android8.0后不允许直接启动后台服务。

Process: com.icourt.alpha.service.LocalService, PID: 4343
java.lang.IllegalStateException: Not allowed to start service Intent { cmp=com.icourt.alpha/.service.LocalService }: app is in background uid UidRecord{81da92c u0a91 SVC  bg:+1m0s13ms idle procs:4 seq(0,0,0)}
at android.app.ContextImpl.startServiceCommon(ContextImpl.java:1505)
at android.app.ContextImpl.startService(ContextImpl.java:1461)
at android.content.ContextWrapper.startService(ContextWrapper.java:644)
at com.icourt.alpha.service.RemoteService$RemoteServiceConnection.onServiceDisconnected(RemoteService.java:100)
at android.app.LoadedApk$ServiceDispatcher.doConnected(LoadedApk.java:1627)
at android.app.LoadedApk$ServiceDispatcher$RunConnection.run(LoadedApk.java:1663)
at android.os.Handler.handleCallback(Handler.java:789)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)

2)前台服务需要附加一个前台通知

要求服务启动以后5秒内必须创建好一个前台通知


    @Override
    public void onCreate() {
        super.onCreate();
        // 创建服务前台通知
        createForegroundNotification();
    }

    /**
     * 创建服务前台通知
     *
     * @author zhouronghua
     * @time 2020/7/22 4:15 PM
     */
    private void createForegroundNotification() {
        if (OSVersionUtils.hasO()) {
            // 8.0以上机型启动一个空的前台通知
            try {
                startForeground(SERVICE_NOTIFY_ID, createServiceNotify());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }


    /**
     * 初始化通知对象(服务初始化使用)
     *
     * @author zhouronghua
     * @time 19-3-28 下午9:12
     */
    public Notification createServiceNotify() {
        Notification notification = null;
        try {
            if (OSVersionUtils.hasO()) {
                NotificationChannel channel = new NotificationChannel(SERVICE_CHANNEL_ID, SERVICE_CHANNEL_NAME,
                    NotificationManager.IMPORTANCE_LOW);
                channel.enableVibration(false);
                channel.enableLights(false);
                NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
                manager.createNotificationChannel(channel);
            }
            notification = (new NotificationCompat.Builder(this, SERVICE_CHANNEL_ID)).build();
        } catch (Exception var3) {
            var3.printStackTrace();
        }
        return notification;
    }

这是通用的Android8.0以后Service的启动方案。

        如果你以为这样就可以了,那不好意思,同学,你是不知道社会的险恶呀。

android.app.RemoteServiceException: Context.startForegroundService() did not then call Service.startForeground()
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2220)
    at android.os.Handler.dispatchMessage(Handler.java:109)
    at android.os.Looper.loop(Looper.java:166)
    at android.app.ActivityThread.main(ActivityThread.java:7555)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:469)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:963)

这样修改以后,Servie友盟的崩溃,能够从4000多下降到800~900,仍然会出现一些闪退。

5秒陷阱并不能够完全解决。

从此,Android8.0以后,作为安卓4大组件的Service开始沦为鸡肋。

谷歌推荐使用WorkManager架构组件来管理后台工作任务。

       WorkManager是Jetpack中一个重要组件。WorkManager相对于Service主要有以下优势:

1.service的滥用导致手机后台任务不断执行,耗电量大。
2.从开发者来说,Android8.0以后,Android对于后台service管理的更加严格,应用在后台启动的服务必须是前台服务,否则会导致应用crash。当然你也可以选择降低targetSdkVersion。
3.针对targetSdkVersion Google也针对的出了一些限制。ps:2019 年起,每次发布新版本后,所有应用都必须在一年内将 Target API 更新到最新版本。

国内对于APP权限的合规和使用进一步严格,要求APP的目标SDK版本必须为26,使用动态授权的方式,随着系统版本的更新,也进一步压缩了Service的生存空间。

因此,将Service进行相应的替代就变得迫切了。

的生存空间。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值