我需要什么配置,以避免 Android 11 在从我的主要任务最小化后杀死我的 SingleInstance Activity?
What configuration do I need, to avoid Android 11 killing my SingleInstance Activity after minimizing from my main task?
我目前的流程如下:
- 用户输入主activityA
- 然后用户启动 activity B,它是单个实例
- Activity B然后启动一个前台服务
启动前台服务的方法
public static void startService(Activity activity) {
Intent serviceIntent = SomeService.newIntent(activity);
ContextCompat.startForegroundService(activity, serviceIntent);
}
服务 onStartCommand
Notification notification = getNotification();
startForeground(1, notification);
return START_NOT_STICKY;
清单
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
...
<activity
android:name="com.proj.activities.ActivityA"
android:screenOrientation="portrait" />
...
<activity
android:name="com.proj.activities.ServiceActivityB"
android:launchMode="singleInstance"
android:screenOrientation="portrait" />
...
<service
android:name="com.proj.SomeService"
android:foregroundServiceType="location" />
以下操作使我的单个实例在 Android 11 和以前的版本上保持活动状态。
- 如果 activity B 最小化,前台服务保持活动状态。
- 如果用户从 activity B (singleInstance) 启动 activity A,前台服务保持活动状态。
Activity A 启动 B:
Intent activityBIntent = new Intent(activity, ServiceActivityB.class);
activity.startActivity(activityBIntent);
日志:
* Task{328c3ce #30946 visible=true type=standard mode=fullscreen translucent=false A=10480:com.company.name U=0 StackId=30946 sz=1}
mLastOrientationSource=ActivityRecord{b2900c9 u0 com.company.name/com.proj.activities.ServiceActivityB t30946}
bounds=[0,0][1080,2280]
* ActivityRecord{b2900c9 u0 com.company.name/com.proj.activities.ServiceActivityB t30946}
* Task{de6d50d #30945 visible=true type=standard mode=fullscreen translucent=false A=10480:com.company.name U=0 StackId=30945 sz=2}
mLastOrientationSource=ActivityRecord{58892bb u0 com.company.name/com.proj.activities.SpringboardActivity 30945}
bounds=[0,0][1080,2280]
* ActivityRecord{58892bb u0 com.company.name/com.proj.activities.ActivityA t30945}
* ActivityRecord{183c336 u0 com.company.name/com.proj.activities.SpringboardActivity t30945}
活动 B 启动 A:
Intent activityAIntent = new Intent(activity, ActivityA.class);
activityAIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
activity.startActivity(activityAIntent);
日志:
* Task{de6d50d #30945 visible=true type=standard mode=fullscreen translucent=false A=10480:com.company.name U=0 StackId=30945 sz=2}
mLastOrientationSource=ActivityRecord{58892bb u0 com.company.name/com.proj.activities.SpringboardActivity t30945}
bounds=[0,0][1080,2280]
* ActivityRecord{58892bb u0 com.company.name/com.proj.activities.ActivityA t30945}
* ActivityRecord{183c336 u0 com.company.name/com.proj.activities.SpringboardActivity t30945}
* Task{328c3ce #30946 visible=true type=standard mode=fullscreen translucent=false A=10480:com.company.name U=0 StackId=30946 sz=1}
mLastOrientationSource=ActivityRecord{b2900c9 u0 com.company.name/com.proj.activities.ServiceActivityB t30946}
bounds=[0,0][1080,2280]
* ActivityRecord{b2900c9 u0 com.company.name/com.proj.activities.ServiceActivityB t30946
但在Android 11中,与之前的Android版本不同,如果用户从activity B(singleInstance)启动activity A,然后最小化应用程序,OnDestroy () 在持有 运行 服务的 activity B 上被调用。
我最初的目标是在 Activity B 中获取位置更新,同时我们的用户仍然可以使用该应用程序(打开其他活动)。保持 Activity B 处于活动状态很重要,因为它有一个无法重新加载的 WebView,否则用户将失去他们的进度。
我能够通过 activity B 上的单实例标志实现这一点,但可能不是正确的方法,因为很明显 Google 改变了管理任务的方式新 Android 11 次更新。
向 Activity B 添加不同的 taskAffinity 可以轻松解决我的任务被终止的问题,但它在最近的应用程序中创建了两个 windows,如果用户用 Activity A.
杀死了 window
我重新构建了我的解决方案,使我的服务成为一个绑定服务,它也可以转到前台,并且它将包含我的 UI 在重新进入 [=21] 时需要的所有必要数据=] B.
https://developer.android.com/guide/components/bound-services
我目前的流程如下:
- 用户输入主activityA
- 然后用户启动 activity B,它是单个实例
- Activity B然后启动一个前台服务
启动前台服务的方法
public static void startService(Activity activity) {
Intent serviceIntent = SomeService.newIntent(activity);
ContextCompat.startForegroundService(activity, serviceIntent);
}
服务 onStartCommand
Notification notification = getNotification();
startForeground(1, notification);
return START_NOT_STICKY;
清单
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
...
<activity
android:name="com.proj.activities.ActivityA"
android:screenOrientation="portrait" />
...
<activity
android:name="com.proj.activities.ServiceActivityB"
android:launchMode="singleInstance"
android:screenOrientation="portrait" />
...
<service
android:name="com.proj.SomeService"
android:foregroundServiceType="location" />
以下操作使我的单个实例在 Android 11 和以前的版本上保持活动状态。
- 如果 activity B 最小化,前台服务保持活动状态。
- 如果用户从 activity B (singleInstance) 启动 activity A,前台服务保持活动状态。
Activity A 启动 B:
Intent activityBIntent = new Intent(activity, ServiceActivityB.class);
activity.startActivity(activityBIntent);
日志:
* Task{328c3ce #30946 visible=true type=standard mode=fullscreen translucent=false A=10480:com.company.name U=0 StackId=30946 sz=1}
mLastOrientationSource=ActivityRecord{b2900c9 u0 com.company.name/com.proj.activities.ServiceActivityB t30946}
bounds=[0,0][1080,2280]
* ActivityRecord{b2900c9 u0 com.company.name/com.proj.activities.ServiceActivityB t30946}
* Task{de6d50d #30945 visible=true type=standard mode=fullscreen translucent=false A=10480:com.company.name U=0 StackId=30945 sz=2}
mLastOrientationSource=ActivityRecord{58892bb u0 com.company.name/com.proj.activities.SpringboardActivity 30945}
bounds=[0,0][1080,2280]
* ActivityRecord{58892bb u0 com.company.name/com.proj.activities.ActivityA t30945}
* ActivityRecord{183c336 u0 com.company.name/com.proj.activities.SpringboardActivity t30945}
活动 B 启动 A:
Intent activityAIntent = new Intent(activity, ActivityA.class);
activityAIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
activity.startActivity(activityAIntent);
日志:
* Task{de6d50d #30945 visible=true type=standard mode=fullscreen translucent=false A=10480:com.company.name U=0 StackId=30945 sz=2}
mLastOrientationSource=ActivityRecord{58892bb u0 com.company.name/com.proj.activities.SpringboardActivity t30945}
bounds=[0,0][1080,2280]
* ActivityRecord{58892bb u0 com.company.name/com.proj.activities.ActivityA t30945}
* ActivityRecord{183c336 u0 com.company.name/com.proj.activities.SpringboardActivity t30945}
* Task{328c3ce #30946 visible=true type=standard mode=fullscreen translucent=false A=10480:com.company.name U=0 StackId=30946 sz=1}
mLastOrientationSource=ActivityRecord{b2900c9 u0 com.company.name/com.proj.activities.ServiceActivityB t30946}
bounds=[0,0][1080,2280]
* ActivityRecord{b2900c9 u0 com.company.name/com.proj.activities.ServiceActivityB t30946
但在Android 11中,与之前的Android版本不同,如果用户从activity B(singleInstance)启动activity A,然后最小化应用程序,OnDestroy () 在持有 运行 服务的 activity B 上被调用。
我最初的目标是在 Activity B 中获取位置更新,同时我们的用户仍然可以使用该应用程序(打开其他活动)。保持 Activity B 处于活动状态很重要,因为它有一个无法重新加载的 WebView,否则用户将失去他们的进度。
我能够通过 activity B 上的单实例标志实现这一点,但可能不是正确的方法,因为很明显 Google 改变了管理任务的方式新 Android 11 次更新。
向 Activity B 添加不同的 taskAffinity 可以轻松解决我的任务被终止的问题,但它在最近的应用程序中创建了两个 windows,如果用户用 Activity A.
杀死了 window我重新构建了我的解决方案,使我的服务成为一个绑定服务,它也可以转到前台,并且它将包含我的 UI 在重新进入 [=21] 时需要的所有必要数据=] B. https://developer.android.com/guide/components/bound-services