Android应用按功能分包后启动崩溃问题排查与修复求助
Android权限申请分包后崩溃问题排查与修复
问题背景
开发一款需要权限授权的Android应用,所有Java类放在根包com.example.permission时运行正常。为整合项目按功能分包(仅MainActivity.java留在根包),修改了包名和变量可见性但未改动业务逻辑,应用启动后立即崩溃。
崩溃报错信息
FATAL EXCEPTION: main Process: com.example.permission, PID: 3291 java.lang.RuntimeException: Unable to resume activity {com.example.permission/com.example.permission.MainActivity}: java.lang.ArrayIndexOutOfBoundsException: length=0; index=0 at android.app.ActivityThread.performResumeActivity(ActivityThread.java:4962) at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:4995) at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:229) at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:205) at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:177) at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:98) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2443) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loopOnce(Looper.java:205) at android.os.Looper.loop(Looper.java:294) at android.app.ActivityThread.main(ActivityThread.java:8177) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:552) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:971) Caused by: java.lang.ArrayIndexOutOfBoundsException: length=0; index=0 at com.example.permission.permission.OnPermissionsResult.onPermissionsResult(OnPermissionsResult.java:49) at com.example.permission.MainActivity.onRequestPermissionsResult(MainActivity.java:104) at android.app.Activity.requestPermissions(Activity.java:5479) at androidx.core.app.ActivityCompat$Api23Impl.requestPermissions(ActivityCompat.java:904) at androidx.core.app.ActivityCompat.requestPermissions(ActivityCompat.java:545) at com.example.permission.permission.CheckPermission.askPermissionBox(CheckPermission.java:171) at com.example.permission.MainActivity.onResume(MainActivity.java:125) at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1603) at android.app.Activity.performResume(Activity.java:8743) at android.app.ActivityThread.performResumeActivity(ActivityThread.java:4952) ...
问题根源
报错指向OnPermissionsResult.java第49行的数组越界:代码直接访问mypermissions[0]但未判断数组是否为空、长度是否大于0。
分包操作本身不影响业务逻辑,但该代码存在潜在bug:当权限请求的permissions数组为空时(比如权限参数传递异常、系统返回空数组等场景),未做判空处理就直接访问索引0,触发崩溃。之前同包运行时未触发该场景,分包后因环境或调用路径变化导致bug暴露。
修复方案
在访问mypermissions数组的索引前,先增加非空和长度校验:
- 在
OnPermissionsResult的onPermissionsResult()方法中,对mypermissions数组增加校验逻辑 - 若数组为空,直接跳过对应分支处理,避免崩溃
- 同时在后续调用
askPermissionBox时,也校验数组非空,从源头避免空数组进入流程
修改后的代码示例
调整OnPermissionsResult.java中的onPermissionsResult()方法:
public void onPermissionsResult() { for (int permission : mygrandResults) { permissionChecker = permissionChecker + permission; } if (permissionChecker == PackageManager.PERMISSION_GRANTED && mygrandResults.length > 0) { OnPermissionGranted onPermissionGranted = new OnPermissionGranted(myrequestCode, mycontext, myactivity); onPermissionGranted.skip_to_next_permission(myrequestCode, myactivity); } // 增加mypermissions非空且长度大于0的判断 else if (mypermissions != null && mypermissions.length > 0 && !ActivityCompat.shouldShowRequestPermissionRationale(myactivity, mypermissions[0])) { AlertDialog.Builder builder = new AlertDialog.Builder(myactivity); builder.setMessage("This feature is unavailable as this feature requires permission that you have denied. Please allow " + mypermissions[0] + " from settings to proceed further.") .setTitle("Permission Required") .setCancelable(false) .setNegativeButton("Cancel", (dialog, which) -> { dialog.dismiss(); }) .setPositiveButton("Settings", (dialog, which) -> { try { dialog.dismiss(); Intent intent = new Intent(); intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); Uri uri = Uri.fromParts("package", myactivity.getPackageName(), null); intent.setData(uri); myactivity.startActivity(intent); } catch (Exception e) { dialog.dismiss(); Intent intent = new Intent(); intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); myactivity.startActivity(intent); } }); builder.show(); } else { // 校验mypermissions非空,避免传递空数组 if (mypermissions != null) { CheckPermission checkPermission = new CheckPermission(mycontext, myactivity); checkPermission.askPermissionBox(mypermissions, myrequestCode); } } }
额外建议:检查CheckPermission类的askPermissionBox方法,确保接收的权限数组不为空,从源头规避空数组进入权限请求流程。
内容的提问来源于stack exchange,提问作者Lo Dennis
相关产品推荐
相关产品推荐

