我有一个imageView,它填充了用户从图库中选择的图像。然后,当单击一个名为“设置背景”的按钮时,此图像用于设置另一个活动的背景。当我选择图像时,它会在imageView中显示,但是当我按下“设置背景”按钮时,我在缩小位图时会得到一个NPE。这是错误:
11-22 21:21:14.174: D/AndroidRuntime(24601): Shutting down VM
11-22 21:21:14.194: E/AndroidRuntime(24601): FATAL EXCEPTION: main
11-22 21:21:14.194: E/AndroidRuntime(24601): java.lang.NullPointerException
11-22 21:21:14.194: E/AndroidRuntime(24601): at com.example.awesomefilebuilderwidget.Personalize.scaleDownBitmap(Personalize.java:119)
11-22 21:21:14.194: E/AndroidRuntime(24601): at com.example.awesomefilebuilderwidget.Personalize.setBackgroundImageInDragAndDrop(Personalize.java:143)
11-22 21:21:14.194: E/AndroidRuntime(24601): at com.example.awesomefilebuilderwidget.Personalize.onClick(Personalize.java:88)
11-22 21:21:14.194: E/AndroidRuntime(24601): at android.view.View.performClick(View.java:2532)
11-22 21:21:14.194: E/AndroidRuntime(24601): at android.view.View$PerformClick.run(View.java:9308)
11-22 21:21:14.194: E/AndroidRuntime(24601): at android.os.Handler.handleCallback(Handler.java:587)
11-22 21:21:14.194: E/AndroidRuntime(24601): at android.os.Handler.dispatchMessage(Handler.java:92)
11-22 21:21:14.194: E/AndroidRuntime(24601): at android.os.Looper.loop(Looper.java:150)
11-22 21:21:14.194: E/AndroidRuntime(24601): at android.app.ActivityThread.main(ActivityThread.java:4333)
11-22 21:21:14.194: E/AndroidRuntime(24601): at java.lang.reflect.Method.invokeNative(Native Method)
11-22 21:21:14.194: E/AndroidRuntime(24601): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
11-22 21:21:14.194: E/AndroidRuntime(24601): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
11-22 21:21:14.194: E/AndroidRuntime(24601): at dalvik.system.NativeStart.main(Native Method)
这是我的个性化课程:
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 static final int RESULT_ICON = 20;
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_ICON, 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);
b2 = getAndDecodeImage(selectedImagePath);
if (b2 != null) {
image2.setImageBitmap(b2);
}
}
}
}
@Override
protected void onPause() {
SharedPreferences sp = getSharedPreferences("AppSharedPref", 1); // open
// shared
// preferences
// with
// name
// AppSharedPref
Editor editor = sp.edit();
editor.putString("ImagePath", selectedImagePath); // Store
// selectedImagePath
// with key
// "ImagePath". This
// key will be then
// used to retrieve
// data.
editor.commit();
super.onPause();
Log.d("Personalize", "onPause() called and selectedImagePath saved");
}
@Override
protected void onResume() {
SharedPreferences sp = getSharedPreferences("AppSharedPref", 1);
selectedImagePath = sp.getString("ImagePath", "");
super.onResume();
Log.d("Personalize", "onResume() called and images uploaded");
Log.d("Personalize", "Now set the image as background");
background = getAndDecodeImage(selectedImagePath);
if (background != null) {
image.setImageBitmap(background);
}
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;
}
}
}
这里更具体地说是行
119
int w= (int) (h * background.getWidth()/((double) background.getHeight()));
143
scaleDownBitmap(background, 500, this.getBaseContext());
显然background
正在返回null,但我无法弄清楚原因。
请帮忙!
增加:
这是通往NPE的LogCat:
11-22 21:33:37.650: D/D&D(25036): LinkToPersonalize called
11-22 21:33:37.710: D/Personalize(25036): OnCreate called
11-22 21:33:37.720: D/Personalize(25036): onResume() called and images uploaded
11-22 21:33:37.720: D/Personalize(25036): Now set the image as background
11-22 21:33:37.720: D/Personalize(25036): selectedImagePath:
11-22 21:33:37.720: D/skia(25036): --- SkImageDecoder::Factory returned null
11-22 21:33:38.300: D/Personalize(25036): launchImageChooser called
11-22 21:33:38.320: D/Personalize(25036): onPause() called and selectedImagePath saved
11-22 21:33:41.593: D/Personalize(25036): selectedImagePath: /mnt/sdcard/paintjoy/112411_143853.png
11-22 21:33:41.643: D/dalvikvm(25036): GC_CONCURRENT freed 80K, 44% free 3178K/5639K, external 3701K/4622K, paused 2ms+2ms
11-22 21:33:41.673: D/dalvikvm(25036): GC_EXTERNAL_ALLOC freed <1K, 44% free 3178K/5639K, external 3701K/4622K, paused 25ms
11-22 21:33:41.693: D/Personalize(25036): onResume() called and images uploaded
11-22 21:33:41.693: D/Personalize(25036): Now set the image as background
11-22 21:33:41.693: D/Personalize(25036): selectedImagePath:
11-22 21:33:41.693: D/skia(25036): --- SkImageDecoder::Factory returned null
11-22 21:33:42.654: D/Personalize(25036): setBackgroundImageInDragAndDrop() called
11-22 21:33:42.654: D/AndroidRuntime(25036): Shutting down VM
更新: 接收课中的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 == RESULT_ICON){
byte[] byteArray = data.getByteArrayExtra("myIconBitmap");
Bitmap myIcon = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length);
setBackgroundImageForIcon(myIcon);
Log.d("Drag_and_Drop_App", "Icon is set");
}
}
了setBackgroundImage:
@SuppressLint("NewApi")
private void setBackgroundImage(Bitmap bitmap) {
RelativeLayout yourBackgroundView = (RelativeLayout) findViewById(R.id.rl_drag_and_drop_app);
Drawable d = new BitmapDrawable(getResources(), bitmap);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
yourBackgroundView.setBackgroundDrawable(d);
} else {
yourBackgroundView.setBackground(d);
Log.d("Drag_and_Drop_App", "Background is set");
}
}
setBackgroundImageForIcon:
@SuppressLint("NewApi")
private void setBackgroundImageForIcon(Bitmap bitmap) {
Log.d("Drag_and_Drop_App", "Icon...");
ImageView ivICON = (ImageView) findViewById(R.id.bwidgetOpen);
BitmapDrawable dq = new BitmapDrawable(getResources(), bitmap);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
// ivICON.setImageDrawable(dq);
ivICON.setImageResource(R.drawable.pattern1);
} else {
// ivICON.setImageDrawable(dq);
ivICON.setImageResource(R.drawable.pattern1);
Log.d("Drag_and_Drop_App", "Icon is set");
}
}
全班(没有无关紧要的事情):
package com.example.awesomefilebuilderwidget;
IMPORTS
public class Drag_and_Drop_App extends Activity {
private static final int SET_BACKGROUND = 10;
private static final int RESULT_ICON = 20;
private ListView mListAppInfo;
// Search EditText
EditText inputSearch;
public AppInfoAdapter adapter;
final SwipeDetector swipeDetector = new SwipeDetector();
//For GridView
private int draggedIndex = -1;
private BaseAdapter adapterGV;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// set layout for the main screen
setContentView(R.layout.drag_and_drop_app);
public Bitmap getThumbnail(String filename) {
Bitmap thumbnail = null;
try {
File filePath = this.getFileStreamPath(filename);
FileInputStream fi = new FileInputStream(filePath);
thumbnail = BitmapFactory.decodeStream(fi);
} catch (Exception ex) {
Log.e("getThumbnail() on internal storage", ex.getMessage());
}
return thumbnail;
}
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
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 == RESULT_ICON){
byte[] byteArray = data.getByteArrayExtra("myIconBitmap");
Bitmap myIcon = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length);
setBackgroundImageForIcon(myIcon);
Log.d("Drag_and_Drop_App", "Icon is set");
}
}
@SuppressLint("NewApi")
private void setBackgroundImage(Bitmap bitmap) {
RelativeLayout yourBackgroundView = (RelativeLayout) findViewById(R.id.rl_drag_and_drop_app);
Drawable d = new BitmapDrawable(getResources(), bitmap);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
yourBackgroundView.setBackgroundDrawable(d);
} else {
yourBackgroundView.setBackground(d);
Log.d("Drag_and_Drop_App", "Background is set");
}
}
@SuppressLint("NewApi")
private void setBackgroundImageForIcon(Bitmap bitmap) {
Log.d("Drag_and_Drop_App", "Icon...");
ImageView ivICON = (ImageView) findViewById(R.id.bwidgetOpen);
BitmapDrawable dq = new BitmapDrawable(getResources(), bitmap);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
// ivICON.setImageDrawable(dq);
ivICON.setImageResource(R.drawable.pattern1);
} else {
// ivICON.setImageDrawable(dq);
ivICON.setImageResource(R.drawable.pattern1);
Log.d("Drag_and_Drop_App", "Icon is set");
}
}
}
答案 0 :(得分:0)
试试这个
更新此方法
private Bitmap getAndDecodeImage(String selectedImagePath) {
try {
// Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeFile(selectedImagePath, o);
// The new size we want to scale to
final int REQUIRED_SIZE = 500;
// Find the correct scale value. It should be the power of 2.
int scale = 1;
while (o.outWidth / scale / 2 >= REQUIRED_SIZE && o.outHeight / scale / 2 >= REQUIRED_SIZE)
scale *= 2;
// Decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
return BitmapFactory.decodeFile(selectedImagePath, o2);
} catch (Throwable e) {
e.printStackTrace();
}
return null;
}
答案 1 :(得分:0)
我认为问题是因为您在实际返回之前保存selectedImagePath
当然,您将selectedImagePath
保存到SharedPreferences
onPause
函数中,
但是在调用onPause
之前会调用onActivityResult
函数,
这意味着您将空值保存到SharedPreferences
并将其返回onResume
,这将导致NPE。
只需将onPause
中的保存部分移至onActivtyResult
的末尾即可使其正常工作。
希望得到这个帮助。