首页 > 解决方案 > 我得到一个由布尔位图引起的空指针

问题描述

我得到了这种空指针,原因是:java.lang.NullPointerException:尝试调用虚拟方法'boolean android.graphics.Bitmap.compress(android.graphics.Bitmap$CompressFormat,int,java.io.OutputStream)'在空对象引用上,这是我的日志猫

E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.umo2.players, PID: 1771
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.umo2.players/com.umo2.players.Profile.AccountSettingsActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.graphics.Bitmap.compress(android.graphics.Bitmap$CompressFormat, int, java.io.OutputStream)' on a null object reference
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2868)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2958)
    at android.app.ActivityThread.-wrap12(Unknown Source:0)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1653)
    at android.os.Handler.dispatchMessage(Handler.java:106)
    at android.os.Looper.loop(Looper.java:164)
    at android.app.ActivityThread.main(ActivityThread.java:6739)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:449)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
 Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.graphics.Bitmap.compress(android.graphics.Bitmap$CompressFormat, int, java.io.OutputStream)' on a null object reference
    at com.umo2.players.Utils.ImageManager.getBytesFromBitmap(ImageManager.java:46)
    at com.umo2.players.Utils.FirebaseMethods.uploadNewPhoto(FirebaseMethods.java:428)
    at com.umo2.players.Profile.AccountSettingsActivity.getIncomingIntent(AccountSettingsActivity.java:90)
    at com.umo2.players.Profile.AccountSettingsActivity.onCreate(AccountSettingsActivity.java:66)
    at android.app.Activity.performCreate(Activity.java:7045)
    at android.app.Activity.performCreate(Activity.java:7036)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1217)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2815)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2958) 
    at android.app.ActivityThread.-wrap12(Unknown Source:0) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1653) 
    at android.os.Handler.dispatchMessage(Handler.java:106) 
    at android.os.Looper.loop(Looper.java:164) 
    at android.app.ActivityThread.main(ActivityThread.java:6739) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:449) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807) 

这是我的图像管理器实用程序

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class ImageManager {
private static final String TAG = "ImageManager";
public static final int IMAGE_SAVE_QUALITY = 90;

public static Bitmap getBitmap(String imgUrl) {
    File imageFile = new File(imgUrl);
    FileInputStream fis = null;
    Bitmap bitmap = null;
    try {
        fis = new FileInputStream(imageFile);
        bitmap = BitmapFactory.decodeStream(fis);
    } catch (FileNotFoundException e) {
        Log.e(TAG, "getBitmap: FileNotFoundException: " + e.getMessage());
    } finally {
        try {
            fis.close();
        } catch (IOException e) {
            Log.e(TAG, "getBitmap: FileNotFoundException: " + e.getMessage());
        }
    }
    return bitmap;
}

/**
 * return byte array from a bitmap
 * quality is greater than 0 but less than 100
 *
 * @param bm
 * @param quality
 * @return
 */
public static byte[] getBytesFromBitmap(Bitmap bm, int quality){
    ByteArrayOutputStream stream = new ByteArrayOutputStream();
  bm.compress(Bitmap.CompressFormat.JPEG, quality, stream);
    return stream.toByteArray();
}

}

这是我的firebase方法

       public void uploadNewPhoto(String photoType, final String caption,final int count, final String imgUrl,
                           Bitmap bm) {
    Log.d(TAG, "uploadNewPhoto: attempting to uplaod new photo.");

    FilePaths filePaths = new FilePaths();

    if (photoType.equals(mContext.getString(R.string.new_photo))){

        Log.d(TAG, "uploadNewPhoto: uploading NEW photo.");

        String user_id = FirebaseAuth.getInstance().getCurrentUser().getUid();
        StorageReference storageReference = mStorageReference
                .child(filePaths.FIREBASE_IMAGE_STORAGE + "/" + user_id + "/photo" + (count + 1));

        //convert image url to bitmap
        if(bm == null){
            bm = com.umo2.players.Utils.ImageManager.getBitmap(imgUrl);
        }

        byte[] bytes = ImageManager.getBytesFromBitmap(bm, 100);

        UploadTask uploadTask = null;
        uploadTask = storageReference.putBytes(bytes);

        uploadTask.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
            @Override
            public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
                String firebaseUrl = Objects.requireNonNull(taskSnapshot.getMetadata().getReference()).getDownloadUrl().toString();

                Toast.makeText(mContext, "photo upload success", Toast.LENGTH_SHORT).show();

                //add the new photo to 'photos' node and 'user_photos' node
                addPhotoToDatabase(caption, firebaseUrl.toString());

                //navigate to the main feed so the user can see their photo
                Intent intent = new Intent(mContext, HomeActivity.class);
                mContext.startActivity(intent);
            }
        }).addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {
                Log.d(TAG, "onFailure: Photo upload failed.");
                Toast.makeText(mContext, "Photo upload failed ", Toast.LENGTH_SHORT).show();
            }
        }).addOnProgressListener(new OnProgressListener<UploadTask.TaskSnapshot>() {
            @Override
            public void onProgress(UploadTask.TaskSnapshot taskSnapshot) {
                double progress = (100 * taskSnapshot.getBytesTransferred()) / taskSnapshot.getTotalByteCount();

                if(progress - 15 > mPhotoUploadProgress){
                    Toast.makeText(mContext, "photo upload progress: " + String.format("%.0f", progress) + "%", Toast.LENGTH_SHORT).show();
                    mPhotoUploadProgress = progress;
                }

                Log.d(TAG, "onProgress: upload progress: " + progress + "% done");
            }
        });

    }
    //case new profile photo
    else if(photoType.equals(mContext.getString(R.string.profile_photo))){
        Log.d(TAG, "uploadNewPhoto: uploading new PROFILE photo");


        String user_id = FirebaseAuth.getInstance().getCurrentUser().getUid();
        StorageReference storageReference = mStorageReference
                .child(filePaths.FIREBASE_IMAGE_STORAGE + "/" + user_id + "/profile_photo");

        //convert image url to bitmap
        if(bm == null){
            bm = com.umo2.players.Utils.ImageManager.getBitmap(imgUrl);
        }

       byte[] bytes = ImageManager.getBytesFromBitmap(bm, 100);

        UploadTask uploadTask = null;
       uploadTask = storageReference.putBytes(bytes);


        uploadTask.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
            @Override
            public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
                String firebaseUrl = Objects.requireNonNull(taskSnapshot.getMetadata().getReference()).getDownloadUrl().toString();

                Toast.makeText(mContext, "photo upload success", Toast.LENGTH_SHORT).show();

                //insert into 'user_account_settings' node
                setProfilePhoto(firebaseUrl.toString());

                ((AccountSettingsActivity)mContext).setViewPager(
                        ((AccountSettingsActivity)mContext).pagerAdapter
                                .getFragmentNumber(mContext.getString(R.string.edit_profile_fragment))
                );

            }
        }).addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {
                Log.d(TAG, "onFailure: Photo upload failed.");
                Toast.makeText(mContext, "Photo upload failed ", Toast.LENGTH_SHORT).show();
            }
        }).addOnProgressListener(new OnProgressListener<UploadTask.TaskSnapshot>() {
            @Override
            public void onProgress(UploadTask.TaskSnapshot taskSnapshot) {
                double progress = (100 * taskSnapshot.getBytesTransferred()) / taskSnapshot.getTotalByteCount();

                if(progress - 15 > mPhotoUploadProgress){
                    Toast.makeText(mContext, "photo upload progress: " + String.format("%.0f", progress) + "%", Toast.LENGTH_SHORT).show();
                    mPhotoUploadProgress = progress;
                }

                Log.d(TAG, "onProgress: upload progress: " + progress + "% done");
            }
        });
    }
    }

最后是我的帐户设置活动

        private void getIncomingIntent(){
    Intent intent = getIntent();

    if(intent.hasExtra(getString(R.string.selected_image))
            || intent.hasExtra(getString(R.string.selected_bitmap))){

        //if there is an imageUrl attached as an extra, then it was chosen from the gallery/photo fragment
        Log.d(TAG, "getIncomingIntent: New incoming imgUrl");
        if(intent.getStringExtra(getString(R.string.return_to_fragment)).equals(getString(R.string.edit_profile_fragment))){

            if(intent.hasExtra(getString(R.string.selected_image))){
                //set the new profile picture
                FirebaseMethods firebaseMethods = new FirebaseMethods(AccountSettingsActivity.this);
                firebaseMethods.uploadNewPhoto(getString(R.string.profile_photo), null, 0,
                        intent.getStringExtra(getString(R.string.selected_image)), null);
            }
            else if(intent.hasExtra(getString(R.string.selected_bitmap))){
                //set the new profile picture
                FirebaseMethods firebaseMethods = new FirebaseMethods(AccountSettingsActivity.this);
                firebaseMethods.uploadNewPhoto(getString(R.string.profile_photo), null, 0,
                        null,(Bitmap) intent.getParcelableExtra(getString(R.string.selected_bitmap)));
            }

        }

    }

    if(intent.hasExtra(getString(R.string.calling_activity))){
        Log.d(TAG, "getIncomingIntent: received incoming intent from " + getString(R.string.profile_activity));
        setViewPager(pagerAdapter.getFragmentNumber(getString(R.string.edit_profile_fragment)));
    }
}

标签: javaandroidbitmap

解决方案


firebaseMethods.uploadNewPhoto(getString(R.string.profile_photo), null, 0,
                    null,(Bitmap) intent.getParcelableExtra(getString(R.string.selected_bitmap)));

您将 imageUrl 作为 null 传递,这是您的第四个参数。所以 fis = new FileInputStream(imageFile); 将返回 null,这就是您收到 NullPointerException 的原因。

由于您已经从意图中获取位图作为可打包的额外内容,请将位图而不是 imageUrl 传递给您的 getBitmap 方法,这样您就有了:

getBitmap(Bitmap bitmap) {
    ByteArrayOutputStream bytes = new ByteArrayOutputStream();
    if (bitmap != null) {
       bitmap.compress(Bitmap.CompressFormat.JPEG, 80, bytes);
    }
    // At this point, you have a compressed bitmap.
}

推荐阅读