Activity 请求权限后重新创建
Activity recreated after asking permissions
这是流程:Activity -> Fragment1 -> Fragment2 -> Fragment3
我有一个带有开关视图的 Fragment3 --> 单击此开关后,我调用一个 viewModel 方法,该方法请求启用此开关所需的权限。
问题是每次我请求许可并允许或拒绝时,都会重新创建 activity 并且 Fragment3 死亡,再次显示第一个片段 (Fragment1)
我试过使用 onSaveInstance 状态,但我不清楚如何在请求许可后取回片段实例而不是重新创建所有内容。
知道如何解决这个问题吗?
Activity:
class Activity : DaggerActivity<DaggerComponent>() {
private val viewModel: ActivityViewModel by injectionViewModels {
activityComponent.activityViewModel
}
override fun onSafeCreate(savedInstanceState: Bundle?) {
super.onSafeCreate(savedInstanceState)
setContentView(R.layout.single_fragment_activity)
if (savedInstanceState != null) {
onRestoreInstanceState(savedInstanceState)
} else
observeViewModel()
}
override fun onSafeResume() {
super.onSafeResume()
viewModel.onCheckFeatureState()
}
private fun observeViewModel() {
observe(viewModel.areAllPermissionsGiven) { areGiven ->
if (areGiven) {
replaceFragment(SettingsFragment(), R.id.fragment_container, false)
} else {
replaceFragment(PermissionsFragment(), R.id.fragment_container, false)
}
}
}}
我的片段:
class MyFragment : DaggerFragment<DaggerComponent>() {
private val viewModel: FragmentViewModel by injectionActivityViewModels {
activityComponent.fragmentViewModel
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
initialize()
}
private fun initialize() {
viewModel.onViewCreated()
toolbar.setNavigationOnClickListener { activity?.onBackPressed() }
initViews()
initObservables()
}
private fun initViews() {
switch.onClick {
viewModel.onToggleMonitoringSecurityClick()
}
}
private fun initObservables() {
observe(viewModel.state) { state ->
switch.isChecked = state.isEnabled
switchText.isGone = state.hasPermission
}
}}
我用来请求许可并使用共享首选项启用该功能的代码:
class Option @AssistedInject constructor(
@Assisted private val permission: Permission,
@Assisted private val dataSource: DataSource,
private val permissionStatus: GetPermissionStatusUseCase,
private val permissionRequest: RequestPermissionUseCase) {
fun isEnabled() = dataSource.isEnabled && hasPermission
suspend fun enable() = withContext(Dispatchers.IO) {
val enable = hasPermission || (permissionRequest(permission) is Response.Success)
if (enable) {
dataSource.isEnabled = true
}
enable
}
fun disable() {
dataSource.isEnabled = false
}
suspend fun toggle() {
if (isEnabled()) {
disable()
} else {
enable()
}
}
val hasPermission
get() = permissionStatus.invoke(permission) == PermissionStatus.ENABLED
@AssistedInject.Factory
interface Factory {
fun create(permission: Permission, dataSource: DataSource): Option
}}
我在一个用例上使用了上面的域对象代码,它向 viewModel 提供了是否具有权限的返回值。
这就是我解决问题的方法:
在清单中为活动添加这一行
android:launchMode="singleTop"
例如:
<activity
android:name=".Activity"
android:label="@string/my_activity"
android:launchMode="singleTop"
</activity>
这是流程:Activity -> Fragment1 -> Fragment2 -> Fragment3
我有一个带有开关视图的 Fragment3 --> 单击此开关后,我调用一个 viewModel 方法,该方法请求启用此开关所需的权限。
问题是每次我请求许可并允许或拒绝时,都会重新创建 activity 并且 Fragment3 死亡,再次显示第一个片段 (Fragment1)
我试过使用 onSaveInstance 状态,但我不清楚如何在请求许可后取回片段实例而不是重新创建所有内容。
知道如何解决这个问题吗?
Activity:
class Activity : DaggerActivity<DaggerComponent>() {
private val viewModel: ActivityViewModel by injectionViewModels {
activityComponent.activityViewModel
}
override fun onSafeCreate(savedInstanceState: Bundle?) {
super.onSafeCreate(savedInstanceState)
setContentView(R.layout.single_fragment_activity)
if (savedInstanceState != null) {
onRestoreInstanceState(savedInstanceState)
} else
observeViewModel()
}
override fun onSafeResume() {
super.onSafeResume()
viewModel.onCheckFeatureState()
}
private fun observeViewModel() {
observe(viewModel.areAllPermissionsGiven) { areGiven ->
if (areGiven) {
replaceFragment(SettingsFragment(), R.id.fragment_container, false)
} else {
replaceFragment(PermissionsFragment(), R.id.fragment_container, false)
}
}
}}
我的片段:
class MyFragment : DaggerFragment<DaggerComponent>() {
private val viewModel: FragmentViewModel by injectionActivityViewModels {
activityComponent.fragmentViewModel
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
initialize()
}
private fun initialize() {
viewModel.onViewCreated()
toolbar.setNavigationOnClickListener { activity?.onBackPressed() }
initViews()
initObservables()
}
private fun initViews() {
switch.onClick {
viewModel.onToggleMonitoringSecurityClick()
}
}
private fun initObservables() {
observe(viewModel.state) { state ->
switch.isChecked = state.isEnabled
switchText.isGone = state.hasPermission
}
}}
我用来请求许可并使用共享首选项启用该功能的代码:
class Option @AssistedInject constructor(
@Assisted private val permission: Permission,
@Assisted private val dataSource: DataSource,
private val permissionStatus: GetPermissionStatusUseCase,
private val permissionRequest: RequestPermissionUseCase) {
fun isEnabled() = dataSource.isEnabled && hasPermission
suspend fun enable() = withContext(Dispatchers.IO) {
val enable = hasPermission || (permissionRequest(permission) is Response.Success)
if (enable) {
dataSource.isEnabled = true
}
enable
}
fun disable() {
dataSource.isEnabled = false
}
suspend fun toggle() {
if (isEnabled()) {
disable()
} else {
enable()
}
}
val hasPermission
get() = permissionStatus.invoke(permission) == PermissionStatus.ENABLED
@AssistedInject.Factory
interface Factory {
fun create(permission: Permission, dataSource: DataSource): Option
}}
我在一个用例上使用了上面的域对象代码,它向 viewModel 提供了是否具有权限的返回值。
这就是我解决问题的方法:
在清单中为活动添加这一行
android:launchMode="singleTop"
例如:
<activity
android:name=".Activity"
android:label="@string/my_activity"
android:launchMode="singleTop"
</activity>