API 26运行正常但API 23(Marshmallow)启动即崩溃求助
刚接触Android开发就碰到版本适配的崩溃问题确实让人头大,别慌,咱们一步步来拆解解决你的问题——毕竟API 23(Android 6.0)是个重要的版本分界点,很多规则从这里开始变了。
先看你给出的Gradle配置:
apply plugin: 'com.android.application' android { compileSdkVersion 26 defaultConfig { applicationId "com.set.www.assignment_1_mobile" minSdkVersion 15 targetSdkVersion 26 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner..." } }
你的minSdkVersion是15,理论上要兼容到Android 4.0,但问题出在API 23,咱们重点看这个版本的特性差异。
第一步:先拿到崩溃的“实锤”——获取日志
崩溃肯定有原因,先找到崩溃日志才能精准定位。你可以这么做:
- 打开Android Studio的Logcat窗口,选择你的API 23模拟器设备;
- 筛选日志级别为
Error,或者直接搜索关键词FATAL EXCEPTION; - 找到崩溃的栈信息,比如是
SecurityException(权限问题)还是NoSuchMethodError(用了高版本API),这是解决问题的关键。
第二步:排查最常见的API 23适配坑
1. 动态权限没处理(API 23核心变化)
API 23开始,Android把权限分成了“普通权限”和“危险权限”(比如读写存储、相机、位置等),危险权限不能只在AndroidManifest.xml里声明,必须在运行时动态申请。如果你的应用启动就用到了这类权限,API 23上直接就会崩溃,而API 26模拟器可能你之前手动给过权限,所以没出问题。
解决步骤:
- 先确认
AndroidManifest.xml里已经声明了需要的权限,比如:<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> - 在代码里使用权限前,先检查是否授权,没授权就申请:
// 检查权限是否已授权 if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { // 弹出权限申请对话框 ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 1001); } else { // 已授权,执行你的业务逻辑 } - 还要处理权限申请的回调,重写
onRequestPermissionsResult方法,判断用户是否同意了权限:@Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == 1001) { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // 用户同意权限,执行操作 } else { // 用户拒绝权限,提示或者做降级处理 } } }
2. 不小心用了API 26+的专属方法
API 26(Android 8.0)新增了一些API,比如NotificationChannel(通知渠道),如果你的代码里直接调用了这些方法,没有做版本判断,在API 23上运行就会抛出NoSuchMethodError导致崩溃。
解决方法是给高版本API加版本判断:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // 只有API 26及以上才执行的代码,比如创建通知渠道 NotificationChannel channel = new NotificationChannel("channel_id", "channel_name", NotificationManager.IMPORTANCE_DEFAULT); NotificationManager manager = getSystemService(NotificationManager.class); manager.createNotificationChannel(channel); }
Android Studio很贴心,当你写了高版本API时,按Alt+Enter就能快速生成版本判断的代码。
3. 依赖库版本不匹配
你的compileSdkVersion是26,要确保依赖的support库版本和它一致,比如appcompat-v7的版本应该是26.x.x,不然可能出现兼容性问题:
dependencies { implementation 'com.android.support:appcompat-v7:26.1.0' // 其他support库也要对应26版本 }
如果用了第三方库,也要确认它的minSdkVersion小于等于15,不然可能在低版本设备上出问题。
第三步:验证修改
改完之后,重新在API 23模拟器上运行,看看是否还崩溃。如果还是有问题,再去看新的崩溃日志,重复上面的步骤排查就行。
内容的提问来源于stack exchange,提问作者Billy

