启动Intent时如何优雅处理SecurityException避免应用崩溃?
解决方案
你的问题核心是SecurityException在BaseActivity的生命周期方法中抛出,子类的try-catch无法覆盖到这些位置——你只在子类的onCreate里包裹了super.onCreate,但如果BaseActivity的其他生命周期(比如onStart/onResume)里执行Location逻辑时抛出异常,子类的catch就捕获不到。另外,当用户动态收回“仅在使用时允许”的权限时,应用会触发生命周期重启,此时权限检查逻辑如果只在启动时执行,就会遗漏。
下面是具体的解决步骤:
1. 前置权限检查(推荐)
在BaseActivity中统一添加权限验证逻辑,在执行任何Location相关操作前先确认权限状态,从根源避免抛出异常:
步骤1:编写权限检查工具方法
在BaseActivity中新增方法,检查是否拥有位置权限:
import android.Manifest; import android.content.Intent; import android.content.pm.PackageManager; import android.net.Uri; import android.provider.Settings; import android.widget.Toast; import androidx.core.content.ContextCompat; import androidx.appcompat.app.AppCompatActivity; public abstract class BaseActivity extends AppCompatActivity { // 检查是否拥有位置权限 protected boolean hasLocationPermission() { return ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED; } // 处理权限缺失的逻辑 protected void handleLocationPermissionMissing() { Toast.makeText(this, "请先授予位置权限", Toast.LENGTH_SHORT).show(); // 跳转到应用权限设置页面 Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); Uri uri = Uri.fromParts("package", getPackageName(), null); intent.setData(uri); startActivity(intent); finish(); // 关闭当前页面,阻止后续逻辑执行 } }
步骤2:在BaseActivity的生命周期中前置检查
在BaseActivity的onCreate或onResume(覆盖动态收回权限的场景)中,先执行权限检查:
@Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 优先检查权限,没有则直接引导设置 if (!hasLocationPermission()) { handleLocationPermissionMissing(); return; } // 后续执行Location相关初始化逻辑(比如初始化LocationManager、调用位置接口等) } // 覆盖权限动态收回的场景 @Override protected void onResume() { super.onResume(); if (!hasLocationPermission()) { handleLocationPermissionMissing(); } }
这样所有继承BaseActivity的页面(比如UpdateStockActivity)都会自动执行权限检查,无需子类重复编写代码。
2. 全局捕获SecurityException(兜底方案)
如果无法修改BaseActivity中的Location逻辑(比如依赖第三方库),可以在BaseActivity中对所有可能抛出异常的生命周期方法添加try-catch:
@Override protected void onStart() { try { super.onStart(); // 这里执行BaseActivity中原本的Location相关逻辑 } catch (SecurityException e) { handleLocationPermissionMissing(); } } @Override protected void onResume() { try { super.onResume(); // 这里执行BaseActivity中原本的Location相关逻辑 } catch (SecurityException e) { handleLocationPermissionMissing(); } }
补充说明
- 你代码中的
implements BaseActivity是笔误,Activity只能继承(extends)其他Activity类,无法实现接口形式的BaseActivity。 - 针对“仅在使用时允许”权限被收回的场景,Android会触发当前Activity的
onResume方法,所以在onResume中重复检查权限能覆盖这种情况。
内容的提问来源于stack exchange,提问作者anta40
相关产品推荐
相关产品推荐

