Attempt to invoke virtual method 'int android.graphics.Bitmap.getWidth()' on a null object reference

在开发Android拼图游戏App时,遇到点击选择相册图片导致App闪退的问题,错误信息显示为'Attempt to invoke virtual method 'int android.graphics.Bitmap.getWidth()' on a null object reference'。经过分析,原因是未申请SD卡读取权限。解决方法包括检查用户是否已授权WRITE_EXTERNAL_STORAGE权限,如果没有则动态申请,并在用户响应后处理结果。通过这些步骤,可以成功打开相册并显示所选图片作为拼图背景。

错误提示:Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'int android.graphics.Bitmap.getWidth()' on a null object reference

出现场景:在实现拼图游戏App中选择相册中图片作为拼图背景时,App闪退报错。

出现原因:通过分析错误提示,

newBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);

由.Bitmap.getWidth()为空->找到传入的bitmap为空->向上寻找bitmap->最终发现是由于没有对SD卡权限进行申请引起的。

解决方法:

        前提:点击‘本地图片’按钮进行选择相册图片

对‘本地图片’按钮设置监听,在onClick方法中,需要进行运行时权限处理,动态申请WRITE_EXTERNAL_STORAGE这个危险权限。原因:相册中的照片都是存储在SD卡上的,我们要从SD卡中读取照片就需要申请这个权限。WRITE_EXTERNAL_STORAGE表示同时授予程序对SD卡读和写的能力。

AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setTitle("选择:");
builder.setItems(mCustomItems, new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int which) {
        if (0 == which){
            // 本地图册
            if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED){//判断用户是否已经授权
                ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},1);//向用户申请授权。
            }else {
                openAlbum();

        }

分析代码:

判断用户是否已经授权,借助的是:ContextCompat.checkSelfPermission(Context, 具体的权限名jian将返回值与PackageManager.PERMISSION_GRANTED作比较,相等说明用户已经授权,不等表示没授权。

ContextCompat.checkSelfPermission(MainActivity.this,Manifest.permission.WRITE_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED

没有授权:调用ActivityCompat.requestPermissions(Activity的实例,String数组(将申请的权限名放入),参数请求码(1))方法向用户申请授权。

ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},1);

调用完requestPermissions()方法,系统会弹出一个权限申请对话框,用户可以选择同意或拒绝我们的权限申请,

无论哪种结果,最终都会回调到onRequestPermissionsResult()方法,此方法中授权结果会封装到grantResults参数中。

@Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        switch (requestCode){
            case 1:
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
                    openAlbum();
                }else {
                    Toast.makeText(this,"You denied the permission",Toast.LENGTH_SHORT).show();
                }
                break;
            default:
        }
    }

openAlbum()方法:打开相册程序选择照片

private void openAlbum(){
        Intent intent = new Intent(Intent.ACTION_PICK, null);//选择数据
        intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,IMAGE_TYPE);
        startActivityForResult(intent, RESULT_IMAGE);//打开相册程序选择照片
}

更改后可以将相册中的图片正常显示作为拼图背景。

Exception configuring surface java.lang.NullPointerException: Attempt to invoke virtual method 'int android.media.Image.getWidth()' on a null object reference at com.tencent.yolov5ncnn.MainActivity.YUV_420_888toNV21(MainActivity.java:336) at com.tencent.yolov5ncnn.MainActivity.processByExtractor(MainActivity.java:412) at com.tencent.yolov5ncnn.MainActivity.-$$Nest$mprocessByExtractor(Unknown Source:0) at com.tencent.yolov5ncnn.MainActivity$3.surfaceCreated(MainActivity.java:522) at android.view.SurfaceView.updateSurface(SurfaceView.java:1369) at android.view.SurfaceView.setWindowStopped(SurfaceView.java:478) at android.view.SurfaceView.surfaceCreated(SurfaceView.java:2117) at android.view.ViewRootImpl.notifySurfaceCreated(ViewRootImpl.java:2758) at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:4269) at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:3076) at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:10643) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1570) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1579) at android.view.Choreographer.doCallbacks(Choreographer.java:1179) at android.view.Choreographer.doFrame(Choreographer.java:1108) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1553) at android.os.Handler.handleCallback(Handler.java:995) at android.os.Handler.dispatchMessage(Handler.java:103) at android.os.Looper.loopOnce(Looper.java:248) at android.os.Looper.loop(Looper.java:338) at android.app.ActivityThread.main(ActivityThread.java:9067) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:593) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:932) 2025-10-31 10:10:38.515 5130-5143 HWUI com.tencent.yolov5ncnn I Davey! duration=1040ms; Flags=1, FrameTimelineVsyncId=47448, IntendedVsync=2598786586062, Vsync=2598786586062, InputEventId=0, HandleInputStart=2598794939800, AnimationStart=2598794980600, PerformTraversalsStart=2598795034100, DrawStart=2599272356200, FrameDeadline=2598803252728, FrameStartTime=2598794914900, FrameInterval=16666666, WorkloadTarget=16666666, SyncQueued=2599272966500, SyncStart=2599283060100, IssueDrawCommandsStart=2599284212300, SwapBuffers=2599321097000, FrameCompleted=2599836984800, DequeueBufferDuration=513035500, QueueBufferDuration=1281600, GpuCompleted=2599337255300, SwapBuffersCompleted=2599836984800, DisplayPresentTime=0, CommandSubmissionCompleted=2599321097000, 2025-10-31 10:10:39.262 5130-5130 Choreographer com.tencent.yolov5ncnn I Skipped 40 frames! The application may be doing too much work on its main thread. 2025-10-31 10:10:39.371 5130-5130 InsetsController com.tencent.yolov5ncnn D hide(ime(), fromIme=false) 2025-10-31 10:10:39.376 5130-5142 HWUI com.tencent.yolov5ncnn I Davey! duration=700ms; Flags=0, FrameTimelineVsyncId=48036, IntendedVsync=2599886586018, Vsync=2599886586018, InputEventId=0, HandleInputStart=2599889017200, AnimationStart=2599889062100, PerformTraversalsStart=2599889119400, DrawStart=2599889248300, FrameDeadline=2599903252684, FrameStartTime=2599888991600, FrameInterval=16666666, WorkloadTarget=16666666, SyncQueued=2599890108800, SyncStart=2599890392400, IssueDrawCommandsStart=2599890455400, SwapBuffers=2599891672300, FrameCompleted=2600587209400, DequeueBufferDuration=689997200, QueueBufferDuration=1223500, GpuCompleted=2599906490200, SwapBuffersCompleted=2600587209400, DisplayPresentTime=0, CommandSubmissionCompleted=2599891672300, 2025-10-31 10:10:39.377 5130-5130 ImeTracker com.tencent.yolov5ncnn I com.tencent.yolov5ncnn:8ee6be8c: onCancelled at PHASE_CLIENT_ALREADY_HIDDEN 2025-10-31 10:10:39.445 5130-5142 HWUI com.tencent.yolov5ncnn I Davey! duration=710ms; Flags=0, FrameTimelineVsyncId=48071, IntendedVsync=2599919919350, Vsync=2600586585990, InputEventId=0, HandleInputStart=2600588783800, AnimationStart=2600588823700, PerformTraversalsStart=2600589829100, DrawStart=2600590021100, FrameDeadline=2600653252654, FrameStartTime=2600588149300, FrameInterval=16666666, WorkloadTarget=16666666, SyncQueued=2600590248700, SyncStart=2600696824300, IssueDrawCommandsStart=2600696930000, SwapBuffers=2600697985900, FrameCompleted=2600736609200, DequeueBufferDuration=227700, QueueBufferDuration=3745900, GpuCompleted=2600736609200, SwapBuffersCompleted=2600703434400, DisplayPresentTime=0, CommandSubmissionCompleted=2600697985900, 2025-10-31 10:10:42.705 5130-5182 BufferPoolAccessor2.0 com.tencent.yolov5ncnn D bufferpool2 0x7fb23d4bc578 : 6(37748736 size) total buffers - 4(25165824 size) used buffers - 0/6 (recycle/alloc) - 5/7 (fetch/transfer) 2025-10-31 10:10:42.705 5130-5182 BufferPoolAccessor2.0 com.tencent.yolov5ncnn D evictor expired: 1, evicted: 1
11-01
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值