【问题标题】:Null pointer exception when scaling down and setting bitmap缩小和设置位图时出现空指针异常
【发布时间】:2013-11-14 23:06:21
【问题描述】:

我有一个按钮,它获取用户选择的图像,然后在 imageView 中设置它(注意:它在视图中显示选定的图像,然后当用户单击按钮时,它在另一个图像视图中设置它) 我在后台的同一个活动中执行了此操作,它运行良好,在查看我的代码后,我不确定 NULL 会发生什么以及如何修复它。这是错误:

11-14 15:56:07.387: E/AndroidRuntime(25894): FATAL EXCEPTION: main
11-14 15:56:07.387: E/AndroidRuntime(25894): java.lang.NullPointerException
11-14 15:56:07.387: E/AndroidRuntime(25894):    at com.example.awesomefilebuilderwidget.Personalize.scaleDownBitmapForIcon(Personalize.java:127)
11-14 15:56:07.387: E/AndroidRuntime(25894):    at com.example.awesomefilebuilderwidget.Personalize.setIconImageInWidget(Personalize.java:98)
11-14 15:56:07.387: E/AndroidRuntime(25894):    at com.example.awesomefilebuilderwidget.Personalize.onClick(Personalize.java:87)
11-14 15:56:07.387: E/AndroidRuntime(25894):    at android.view.View.performClick(View.java:2532)
11-14 15:56:07.387: E/AndroidRuntime(25894):    at android.view.View$PerformClick.run(View.java:9308)
11-14 15:56:07.387: E/AndroidRuntime(25894):    at android.os.Handler.handleCallback(Handler.java:587)
11-14 15:56:07.387: E/AndroidRuntime(25894):    at android.os.Handler.dispatchMessage(Handler.java:92)
11-14 15:56:07.387: E/AndroidRuntime(25894):    at android.os.Looper.loop(Looper.java:150)
11-14 15:56:07.387: E/AndroidRuntime(25894):    at android.app.ActivityThread.main(ActivityThread.java:4333)
11-14 15:56:07.387: E/AndroidRuntime(25894):    at java.lang.reflect.Method.invokeNative(Native Method)
11-14 15:56:07.387: E/AndroidRuntime(25894):    at java.lang.reflect.Method.invoke(Method.java:507)
11-14 15:56:07.387: E/AndroidRuntime(25894):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
11-14 15:56:07.387: E/AndroidRuntime(25894):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
11-14 15:56:07.387: E/AndroidRuntime(25894):    at dalvik.system.NativeStart.main(Native Method)

这是我的 Personalize.java:

public class Personalize extends Activity implements View.OnClickListener
{
    Button button;
    ImageView image;
    ImageView image2;
    Button btnChangeImage;
    Button btnChangeImageForIcon;
    Button btnSetBackground;
    private static final int SELECT_PICTURE = 1;
    private static final int SELECT_PICTURE_2 = 2;
    private String selectedImagePath;
    Bitmap background;
    Bitmap b2;

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.personalize);
        Log.d("Personalize", "OnCreate called");

        image = (ImageView) findViewById(R.id.imageView1);
        image2 = (ImageView) findViewById(R.id.imageView2Icon);

        Button btnChangeImage = (Button) findViewById(R.id.btnChangeImage);
        btnChangeImage.setOnClickListener(this);

        Button btnChangeImageForIcon = (Button) findViewById(R.id.btnChangeImageForIcon);
        btnChangeImageForIcon.setOnClickListener(this);

        Button btnSetBackground = (Button) findViewById(R.id.btnSetBackground);
        btnSetBackground.setOnClickListener(this);

        Button btnLinkToFeedback = (Button) findViewById(R.id.btnLinkToFeedback);

        Button btnSetIcon = (Button) findViewById(R.id.btnSetIcon);
        btnSetIcon.setOnClickListener(this);

        // Link to Feedback Screen
        btnLinkToFeedback.setOnClickListener(new View.OnClickListener() {

            public void onClick(View view)
            {
                Intent i = new Intent(getApplicationContext(), Feedback.class);
                startActivity(i);
                Log.d("Personalize", "LinkToFeedBack called");
                finish();
            }
        });

    }

    @Override
    public void onClick(View v)
    {
        switch (v.getId()) {
            case R.id.btnChangeImage:
                launchImageChooser();
                break;
            case R.id.btnChangeImageForIcon:
                launchImageChooser2();
                break;
            case R.id.btnSetBackground:
                setBackgroundImageInDragAndDrop();
                break;
            case R.id.btnSetIcon:
                setIconImageInWidget();
                break;
        }
    }

    private void setIconImageInWidget()
    {
        // TODO Auto-generated method stub
        Log.d("Personalize", "setIconImageInWidget() called");
        Intent i = getIntent();
        // Convert bitmap to byte array to send back to activity
        // See: http://stackoverflow.com/questions/11010386/send-bitmap-using-intent-android
        scaleDownBitmapForIcon(b2, 500, this.getBaseContext());
        Log.d("Personalize", "Scale Bitmap Chosen For Icon");
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        b2.compress(Bitmap.CompressFormat.PNG, 100, stream);
        byte[] byteArray = stream.toByteArray();

        i.putExtra("myIconBitmap", byteArray);
        setResult(RESULT_OK, i);
        finish();
    }

    public static Bitmap scaleDownBitmap(Bitmap background, int newHeight, Context c)
    {

        final float densityMultiplier = c.getResources().getDisplayMetrics().density;

        int h = (int) (500 * densityMultiplier);
        int w = (int) (h * background.getWidth() / ((double) background.getHeight()));

        background = Bitmap.createScaledBitmap(background, w, h, true);
        // TO SOLVE LOOK AT HERE:http://stackoverflow.com/questions/15517176/passing-bitmap-to-
        // other-activity-getting-message-on-logcat-failed-binder-transac
        return background;
    }

    public static Bitmap scaleDownBitmapForIcon(Bitmap b2, int newHeight, Context c)
    {

        final float densityMultiplier = c.getResources().getDisplayMetrics().density;

        int h = (int) (500 * densityMultiplier);
        int w = (int) (h * b2.getWidth() / ((double) b2.getHeight()));

        b2 = Bitmap.createScaledBitmap(b2, w, h, true);
        // TO SOLVE LOOK AT
        // HERE:http://stackoverflow.com/questions/15517176/passing-bitmap-to-other-activity-getting-message-on-logcat-failed-binder-transac
        return b2;
    }

    private void setBackgroundImageInDragAndDrop()
    {
        Log.d("Personalize", "setBackgroundImageInDragAndDrop() called");
        Intent i = getIntent();
        // Convert bitmap to byte array to send back to activity
        // See: http://stackoverflow.com/questions/11010386/send-bitmap-using-intent-android
        scaleDownBitmap(background, 500, this.getBaseContext());
        Log.d("Personalize", "Scale Bitmap Chosen");
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        background.compress(Bitmap.CompressFormat.PNG, 100, stream);
        byte[] byteArray = stream.toByteArray();

        i.putExtra("myBackgroundBitmap", byteArray);
        setResult(RESULT_OK, i);
        finish();
    }

    private void launchImageChooser()
    {
        Intent intent = new Intent();
        intent.setType("image/*");
        intent.setAction(Intent.ACTION_GET_CONTENT);
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        startActivityForResult(intent, SELECT_PICTURE);
        Log.d("Personalize", "launchImageChooser called");
    }

    private void launchImageChooser2()
    {
        Intent intent = new Intent();
        intent.setType("image/*");
        intent.setAction(Intent.ACTION_GET_CONTENT);
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        startActivityForResult(intent, SELECT_PICTURE_2);
        Log.d("Personalize", "launchImageChooser2 called");
    }

    public String getPath(Uri uri)
    {
        String[] projection = { MediaStore.Images.Media.DATA };
        Cursor cursor = getContentResolver().query(uri, projection, null, null, null);
        int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        cursor.moveToFirst();
        String imagePath = cursor.getString(column_index);
        if (cursor != null) {
            cursor.close();
        }
        return imagePath;
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data)
    {

        if (resultCode == RESULT_OK) {
            if (requestCode == SELECT_PICTURE) {
                Uri selectedImageUri = data.getData();
                selectedImagePath = getPath(selectedImageUri);
                background = getAndDecodeImage(selectedImagePath);
                if (background != null) {
                    image.setImageBitmap(background);
                }
            } else if (requestCode == SELECT_PICTURE_2) {
                Uri selectedImageUri = data.getData();
                selectedImagePath = getPath(selectedImageUri);
                Bitmap b2 = getAndDecodeImage(selectedImagePath);
                if (b2 != null) {
                    image2.setImageBitmap(b2);
                }
            }
        }
    }

    private Bitmap getAndDecodeImage(String selectedImagePath)
    {
        try {
            Log.d("Personalize", "selectedImagePath: " + selectedImagePath);
            FileInputStream fileis = new FileInputStream(selectedImagePath);
            BufferedInputStream bufferedstream = new BufferedInputStream(fileis);
            byte[] bMapArray = new byte[bufferedstream.available()];
            bufferedstream.read(bMapArray);
            Bitmap bMap = BitmapFactory.decodeByteArray(bMapArray, 0, bMapArray.length);

            if (fileis != null) {
                fileis.close();
            }
            if (bufferedstream != null) {
                bufferedstream.close();
            }
            return bMap;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    public boolean saveImageToInternalStorage(Bitmap image)
    {
        try {
            FileOutputStream fos = this.openFileOutput("desiredFilename.png", Context.MODE_PRIVATE);
            image.compress(Bitmap.CompressFormat.PNG, 100, fos);
            fos.close();
            return true;
        } catch (Exception e) {
            return false;
        }
    }

}

谢谢!

新的 NPE:

11-14 16:47:54.498: E/AndroidRuntime(27568): FATAL EXCEPTION: main
11-14 16:47:54.498: E/AndroidRuntime(27568): java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=10, result=-1, data=Intent { cmp=com.example.awesomefilebuilderwidget/.Personalize (has extras) }} to activity {com.example.awesomefilebuilderwidget/com.example.awesomefilebuilderwidget.Drag_and_Drop_App}: java.lang.NullPointerException
11-14 16:47:54.498: E/AndroidRuntime(27568):    at android.app.ActivityThread.deliverResults(ActivityThread.java:2974)
11-14 16:47:54.498: E/AndroidRuntime(27568):    at android.app.ActivityThread.handleSendResult(ActivityThread.java:3026)
11-14 16:47:54.498: E/AndroidRuntime(27568):    at android.app.ActivityThread.access$2000(ActivityThread.java:135)
11-14 16:47:54.498: E/AndroidRuntime(27568):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1071)
11-14 16:47:54.498: E/AndroidRuntime(27568):    at android.os.Handler.dispatchMessage(Handler.java:99)
11-14 16:47:54.498: E/AndroidRuntime(27568):    at android.os.Looper.loop(Looper.java:150)
11-14 16:47:54.498: E/AndroidRuntime(27568):    at android.app.ActivityThread.main(ActivityThread.java:4333)
11-14 16:47:54.498: E/AndroidRuntime(27568):    at java.lang.reflect.Method.invokeNative(Native Method)
11-14 16:47:54.498: E/AndroidRuntime(27568):    at java.lang.reflect.Method.invoke(Method.java:507)
11-14 16:47:54.498: E/AndroidRuntime(27568):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
11-14 16:47:54.498: E/AndroidRuntime(27568):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
11-14 16:47:54.498: E/AndroidRuntime(27568):    at dalvik.system.NativeStart.main(Native Method)
11-14 16:47:54.498: E/AndroidRuntime(27568): Caused by: java.lang.NullPointerException
11-14 16:47:54.498: E/AndroidRuntime(27568):    at com.example.awesomefilebuilderwidget.Drag_and_Drop_App.onActivityResult(Drag_and_Drop_App.java:180)
11-14 16:47:54.498: E/AndroidRuntime(27568):    at android.app.Activity.dispatchActivityResult(Activity.java:4053)
11-14 16:47:54.498: E/AndroidRuntime(27568):    at android.app.ActivityThread.deliverResults(ActivityThread.java:2970)
11-14 16:47:54.498: E/AndroidRuntime(27568):    ... 11 more

onActivityResult(如错误所述):

     @Override 
     protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
     super.onActivityResult(requestCode, resultCode, data); 
     Log.i("Drag_and_Drop_App", "requestCode: " + requestCode + ", resultCode: " + resultCode); 
     if(requestCode == SET_BACKGROUND && resultCode == RESULT_OK){ 
     byte[] byteArray = data.getByteArrayExtra("myBackgroundBitmap"); 
     Bitmap myBackground = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length); 
     setBackgroundImage(myBackground); 
     } 
     else if(requestCode == SET_ICON && resultCode == RESULT_OK){
         byte[] byteArray = data.getByteArrayExtra("myIconBitmap"); 
         Bitmap myIcon = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length); 
         setBackgroundImageForIcon(myIcon); 
     }
     } 

【问题讨论】:

  • 我猜你的位图 'b2' 是空的。尝试使用调试器来解决。
  • 看起来是这样......但我不明白为什么它返回 null

标签: android nullpointerexception


【解决方案1】:

b2null 因为在这里

 int w = (int) (h * b2.getWidth() / ((double) b2.getHeight()));

 b2 = Bitmap.createScaledBitmap(b2, w, h, true);

在第一行中,您尝试对其调用方法getHeight(),但直到第二行才对其进行初始化,因此当您尝试初始化w 时,b2 仍然是null

【讨论】:

  • 我有点明白你的意思。当你说“......直到第二行才初始化它所以当你尝试初始化w 然后b2 仍然是null”时我很困惑,因为我以为我之前定义了w我在第二行使用它。也许我只是误会了。
  • 您对w 所做的一切都很好。但那时b2 仍然是null,因为你还没有给它一个值。所以当你在b2(一个空对象)上调用一个方法时,你会得到一个NPE。您需要一种不同的方式来执行此操作,因为每个变量的初始化都依赖于另一个。
  • 好吧,我明白你的意思了,是的,这是有道理的。实际上,在再次查看我的编码之后,我发现在这一行 Bitmap b2 = getAndDecodeImage... 上我有额外的位图声明,所以我删除了它并修复了我得到的 NPE,但现在我得到了一个新的说法它未能提供我的结果。这仍然是由b2 如上所述返回 null 引起的吗?
  • 可能,但我不知道这意味着什么或它来自哪里,“无法提供我的结果”
  • 请查看我在问题中添加错误的新 NPE 部分...我也会添加我的 OnResult 部分(如错误中所述)
猜你喜欢
  • 1970-01-01
  • 2016-04-16
  • 2013-09-02
  • 2021-06-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多