在Service中后台startActivity没反应的原因

在Service中后台startActivity启用应用程序中的页面没反应的揭秘

问题

当我在A应用启动一个服务,在服务中开启一个线程, 当我们手动滑动杀死APP时,服务还是活着的,我们希望重新拉起APP应用,我们可能尝试如下代码,有时候可以拉起来,有时候没有任何反应,但是从日志来看,服务运行正常,心跳的日志正常打印。

public class StepService extends Service {
    private static final String TAG = "StepService";

    public static boolean isRemoveTask = false;

    private Handler handler = new Handler(Looper.getMainLooper());

    private SvrBinder mBinder;

    private ServiceConnection connection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.e(TAG, "<Stub> StepService Connected.");
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
//            Toast.makeText(RemoteService.this,"链接断开,重新启动 LocalService",Toast.LENGTH_LONG).show();
            Log.e(TAG, "<Stub> StepService Disconnected.");
 //           startService(new Intent(StepService.this, GuardService.class));
//            bindService(new Intent(StepService.this, GuardService.class), this , Context.BIND_IMPORTANT);
            Log.e(TAG, "<Stub> StepService Disconnected end.");
        }
    };

    @Override
    public void onCreate() {
        super.onCreate();
        Log.e(TAG, "<Stub> StepService onCreate.");

        String CHANNEL_ONE_ID = "StepServiceId";
        String CHANNEL_ONE_NAME = "StepServiceChannel";
        String CHANNEL_ID = "StepServiceChannelId";

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channel = new NotificationChannel(CHANNEL_ONE_ID, CHANNEL_ONE_NAME, NotificationManager.IMPORTANCE_LOW);
            NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
            if (manager == null)
                return;
            manager.createNotificationChannel(channel);
            Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
                    .setAutoCancel(true)
                    .setCategory(Notification.CATEGORY_SERVICE)
                    .setOngoing(true)
                    .setPriority(NotificationManager.IMPORTANCE_LOW)
                    .build();
        }

        isHeartBeatThread = true;
        if (heartBeatThread == null  || !heartBeatThread.isAlive()){
            heartBeatThread = new HeartBeatThread();
            heartBeatThread.start();
        }

//        startService(new Intent(StepService.this, GuardService.class));
//        bindService(new Intent(StepService.this, GuardService.class),connection,Context.BIND_IMPORTANT);

        Log.e(TAG, "<Stub> StepService isRemoveTask:" + isRemoveTask);

        if (isRemoveTask){
/*            Intent intent = new Intent(getBaseContext(), MainActivity.class);
            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            getApplicationContext().startActivity(intent);*/
        }
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
//        Toast.makeText(this,"RemoteService 启动",Toast.LENGTH_LONG).show();
        Log.e(TAG, "<Stub> StepService onStartCommand.");
        return START_STICKY;
    }



    @Override
    public IBinder onBind(Intent intent) {
        mBinder = new SvrBinder();
        return mBinder;
    }

    private HeartBeatThread heartBeatThread;
    private boolean isHeartBeatThread;
    class HeartBeatThread extends Thread{

        @Override
        public void run() {
            super.run();
            while (isHeartBeatThread){
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                Log.e(TAG, "HeartBeatThread on on on");
            }
        }
    }

    /**
     * 用于客户端绑定器的类。因为我们知道这个服务总是运行在与其客户机相同的进程中,
     * 所以我们不需要处理IPC。
     */
    public class SvrBinder extends IStepServiceAidlInterface.Stub {
        @Override
        public void keepAlive() throws RemoteException {
            Log.e(TAG, "<Stub> StepService keepAlive.");
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        isHeartBeatThread = false;
        unbindService(connection);
        Log.e(TAG, "<Stub> StepService onDestroy.");
    }

    @Override
    public boolean onUnbind(Intent intent) {
        return super.onUnbind(intent);
    }

    @Override
    public void onTaskRemoved(Intent rootIntent) {
        super.onTaskRemoved(rootIntent);

        isRemoveTask = true;
        Log.e(TAG, "<Stub> StepService onTaskRemoved.");

/*        Intent intent = new Intent(getBaseContext(), MainActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        getApplicationContext().startActivity(intent);*/


/*        Intent intent = getBaseContext().getPackageManager()
                .getLaunchIntentForPackage(getBaseContext().getPackageName());
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
        PendingIntent restartIntent = PendingIntent.getActivity(getApplicationContext(), 0, intent, PendingIntent.FLAG_ONE_SHOT);
        AlarmManager mgr = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
        mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 1000, restartIntent); // 1秒钟后重启应用*/


        Intent k = getBaseContext().getPackageManager()
                .getLaunchIntentForPackage(getBaseContext().getPackageName());
        k.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        k.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(k);

  //      stopForeground(true);
 //       unbindService(connection);
 //       stopSelf();
    }

在这里插入图片描述

服务中的代码很简单。

分析

后来发现原因是因为Android10以后是不允许后台去startActivity的。如下图所示
在这里插入图片描述

解决方法

添加权限

    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>

该权限需要用户主动去开启。

        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
            if (!Settings.canDrawOverlays(this)) {
                startActivity(new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + getPackageName())));
            }
        } else {
            Toast.makeText(getApplicationContext(), "API < " + android.os.Build.VERSION_CODES.M, Toast.LENGTH_SHORT).show();
        }

再次重试,杀掉程序后,APP主页面马上启动起来了,完美解决。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

五一编程

程序之路有我与你同行

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值