调用AllowingAccessCamera类出现空对象引用错误求助
问题分析与解决方案
你的错误根源在于错误地手动初始化了Activity子类AllowingAccessCamera。Android中的Activity实例必须由系统通过Intent启动创建,不能直接用new AllowingAccessCamera(this)这种方式手动实例化——否则该Activity的Context并未被系统正确初始化,调用任何依赖Context的方法(比如权限请求)都会触发空指针异常。
步骤1:重构AllowingAccessCamera为权限工具类
把它改成普通类,不再继承AppCompatActivity,而是通过构造函数接收Activity实例来处理权限逻辑:
// AllowingAccessCamera.kt package com.example.mindsync import android.Manifest import android.content.pm.PackageManager import android.widget.Toast import androidx.appcompat.app.AppCompatActivity import androidx.core.app.ActivityCompat class AllowingAccessCamera(private val activity: AppCompatActivity) { private val CAMERA_PERMISSION_REQUEST_CODE = 100 fun requestCameraPermission() { ActivityCompat.requestPermissions( activity, arrayOf(Manifest.permission.CAMERA), CAMERA_PERMISSION_REQUEST_CODE ) } fun handlePermissionResult(requestCode: Int, grantResults: IntArray) { if (requestCode == CAMERA_PERMISSION_REQUEST_CODE) { if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) { showToast(activity.getString(R.string.camera_permission_granted)) } else { showToast(activity.getString(R.string.camera_permission_not_granted)) } } } private fun showToast(message: String) { Toast.makeText(activity, message, Toast.LENGTH_SHORT).show() } }
步骤2:修改IntroActivity代码适配工具类
在IntroActivity中正确初始化工具类,并处理权限回调:
// IntroActivity.kt package com.example.mindsync import android.content.Intent import android.content.SharedPreferences import android.content.pm.PackageManager import android.os.Bundle import android.widget.Button import androidx.appcompat.app.AppCompatActivity class IntroActivity : AppCompatActivity() { private lateinit var sharedPreferences: SharedPreferences private lateinit var permissions: AllowingAccessCamera private var currentScreen = 1 private val totalScreens = 2 // 引导页总数 override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) sharedPreferences = getSharedPreferences("MyPrefs", MODE_PRIVATE) // 提前初始化权限工具类,传入当前Activity实例 permissions = AllowingAccessCamera(this) // 检查是否首次打开应用 if (isFirstTime()) { showIntroScreen() } else { startActivity(Intent(this, MainActivity::class.java)) finish() } } private fun isFirstTime(): Boolean { return sharedPreferences.getBoolean("firstTime", true) } private fun showIntroScreen() { // 设置当前引导页布局 when (currentScreen) { 1 -> setContentView(R.layout.getting_started) 2 -> setContentView(R.layout.allowing_access_to_camera) } // 首页按钮点击事件 findViewById<Button>(R.id.getting_started)?.setOnClickListener { handleIntroButtonClick() } // 相机权限请求按钮点击事件 findViewById<Button>(R.id.cam_request_permission)?.setOnClickListener { permissions.requestCameraPermission() } } private fun handleIntroButtonClick() { if (currentScreen < totalScreens) { currentScreen++ showIntroScreen() } else { // 标记应用已首次打开 val editor = sharedPreferences.edit() editor.putBoolean("firstTime", false) editor.apply() // 转场动画 overridePendingTransition(R.anim.slide_in_right, R.anim.slide_out_left) // 跳转到主页面 startActivity(Intent(this, MainActivity::class.java)) finish() } } // 重写权限回调方法,交给工具类处理 override fun onRequestPermissionsResult( requestCode: Int, permissions: Array<out String>, grantResults: IntArray ) { super.onRequestPermissionsResult(requestCode, permissions, grantResults) this.permissions.handlePermissionResult(requestCode, grantResults) } }
额外说明
- 之前
AllowingAccessCamera作为Activity的onCreate方法和布局设置完全多余,因为引导页布局已经由IntroActivity控制。 - 权限请求必须依附于已被系统初始化的Activity实例,工具类持有
IntroActivity引用是安全的(注意不要在异步任务中长时间持有,避免内存泄漏)。
内容的提问来源于stack exchange,提问作者Bertrandho
相关产品推荐
相关产品推荐

