使用 Intent 在活动之间传递字节数组时如何修复 'FATAL EXCEPTION'?

How to fix 'FATAL EXCEPTION' when passing byte array between Activities using Intent?

通过意图将字节数组从一个 activity 传递到另一个时出现以下错误。我不确定是因为数组太大,还是其他原因。这是错误:

E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.roshan.android.picscheduler, PID: 19689
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.roshan.android.picscheduler/com.roshan.android.picscheduler.ImageDetectActivity}: java.lang.NullPointerException: Attempt to get length of null array
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2955)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3030)
    at android.app.ActivityThread.-wrap11(Unknown Source:0)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1696)
    at android.os.Handler.dispatchMessage(Handler.java:105)
    at android.os.Looper.loop(Looper.java:164)
    at android.app.ActivityThread.main(ActivityThread.java:6938)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)
 Caused by: java.lang.NullPointerException: Attempt to get length of null array
    at com.roshan.android.picscheduler.ImageDetectActivity.onCreate(ImageDetectActivity.java:40)
    at android.app.Activity.performCreate(Activity.java:7183)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1220)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2908)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3030) 
    at android.app.ActivityThread.-wrap11(Unknown Source:0) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1696) 
    at android.os.Handler.dispatchMessage(Handler.java:105) 
    at android.os.Looper.loop(Looper.java:164) 
    at android.app.ActivityThread.main(ActivityThread.java:6938) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374) 

在主activity中,我有这个代码:

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    ButterKnife.bind(this);

    mCameraView.setCameraListener(new CameraKitView.CameraListener() {
        @Override
        public void onOpened() {

        }

        @Override
        public void onClosed() {

        }
    });

    mCameraButton.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View view) {

            mCameraView.captureImage(new CameraKitView.ImageCallback() {
                @Override
                public void onImage(CameraKitView cameraKitView, byte[] bytes) {
                    imageBytes = bytes;

                }
            });



            Intent intent = new Intent(MainActivity.this.getApplicationContext(), ImageDetectActivity.class);
            intent.putExtra("CapturedImage", imageBytes);
            intent.putExtra("width", mCameraView.getWidth());
            intent.putExtra("height", mCameraView.getHeight());
            startActivity(intent);

            //TODO: Launch new activity, pass the bitmap
            // Maybe use Fragments instead of new activity?
        }
    });
}

在目标 activity 的 onCreate 方法中,我有这个:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_image_detect);

    intent = getIntent();
    imageBytes = intent.getByteArrayExtra("CapturedImage");
    cameraWidth = intent.getIntExtra("width", 0);
    cameraHeight = intent.getIntExtra("height", 0);

    bitmap = BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length);
    bitmap = Bitmap.createScaledBitmap(bitmap, cameraWidth, cameraHeight, false);

    image = FirebaseVisionImage.fromBitmap(bitmap);
    detector = FirebaseVision.getInstance().getOnDeviceTextRecognizer();

    result = detector.processImage(image)
            .addOnSuccessListener(new OnSuccessListener<FirebaseVisionText>() {
                @Override
                public void onSuccess(FirebaseVisionText firebaseVisionText) {
                    String resultText = firebaseVisionText.getText();
                    Log.d("TEST", resultText);
                }
            })
            .addOnFailureListener(new OnFailureListener() {
                @Override
                public void onFailure(@NonNull Exception e) {

                }
            });
}

我一尝试解码字节数组就抛出错误,我认为这意味着它接收到一个空数组。

发生错误是因为您从意图中获取的字节数组 为空。

可能的原因:

1. 您从原始 Activity.

传递了一个空字节数组

2. 在向 Intent 添加额外内容然后从 Intent 取回它时,您没有使用完全相同的字符串。

我建议调试你的代码,很多NullPointerExceptions可以通过简单的调试解决。

这个回调

mCameraView.captureImage(new CameraKitView.ImageCallback() {
    @Override
    public void onImage(CameraKitView cameraKitView, byte[] bytes) {
        imageBytes = bytes;
    }
});

叫做异步。这意味着如果您想将字节添加到意图中,则需要将意图代码移至该回调中。

完整的 onClick 调用需要更改为:

mCameraButton.setOnClickListener(new View.OnClickListener() {

    @Override
    public void onClick(View view) {

        mCameraView.captureImage(new CameraKitView.ImageCallback() {
            @Override
            public void onImage(CameraKitView cameraKitView, byte[] bytes) {
                imageBytes = bytes;

                Intent intent = new Intent(MainActivity.this.getApplicationContext(), ImageDetectActivity.class);
                intent.putExtra("CapturedImage", imageBytes);
                intent.putExtra("width", mCameraView.getWidth());
                intent.putExtra("height", mCameraView.getHeight());
                startActivity(intent);
            }
        });
    }
});

这可能会解决您将字节传递给下一个 activity 的问题,但此代码也可能导致用户交互(点击)与 "stuff" 发生在 [=22] 之间的延迟=] 所以用户会感到滞后。你应该考虑改进它(但这超出了这个问题的范围)