我的应用程序拍摄两张图片并将每个 URI 放入一个 ArrayList 中,以便我可以从单个 ImageView 对其进行迭代。我知道 URI 工作正常并已添加到 ArrayList 中。我假设 Activity 在屏幕上因相机旋转而消失(以拍摄前面提到的图像),因此我使用 onSaveInstanceState 来保留我想要使用的数据。在我这样做之前,应用程序会在拍照后立即崩溃。现在没有,但当我尝试从列表中设置图像时,我得到一个 NullPointer 。我做错了什么吗?
日志猫:
FATAL EXCEPTION: main
Process: my.package.myapplication, PID: 15047
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ImageView.setImageURI(android.net.Uri)' on a null object reference
at my.package.myapplication.Person1Screen$5.onClick(Person1Screen.java:130)
at android.view.View.performClick(View.java:5209)
at android.view.View$PerformClick.run(View.java:21174)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5477)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
我在下面的setImageURI中得到了NullPointer:
happy = (Button) findViewById(R.id.happy_btn);
happy.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view){
id = HAPPY;
if(toggled){
//picture mode
dispatchTakePictureIntent();
}
else if(!toggled) {
//display mode
//happyIndex = 0;
mainView.setImageURI(happyList.get(0)); // LINE 130
}
}
});
我的 onCreate 中有以下内容:
happyList = new ArrayList<>();
if (savedInstanceState != null) {
happyList = savedInstanceState.getParcelableArrayList(HAPPY_LIST);
}
我的onSaveInstance:
@Override
public void onSaveInstanceState (Bundle savedInstanceState) {
savedInstanceState.putParcelableArrayList(HAPPY_LIST, happyList);
super.onSaveInstanceState(savedInstanceState);
}
My TakePictureIntent(从相机或图库拍摄两张照片)和 onActivityResult(获取 URI 并添加到列表):
private void dispatchTakePictureIntent() {
pictureCounter = -1;
for(int i = 0; i < 2; i++) {
pictureCounter++;
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
// Create the File where the photo should go
File photoFile = null;
try {
photoFile = createImageFile();
outputFileUri = Uri.fromFile(photoFile);
} catch (IOException ex) {
Log.w("error","IOException");
}catch (NullPointerException nullEx) {
Log.w("error","NullPointerException");
}
// Camera.
final List<Intent> cameraIntents = new ArrayList<Intent>();
final Intent captureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
final PackageManager packageManager = getPackageManager();
final List<ResolveInfo> listCam = packageManager.queryIntentActivities(captureIntent, 0);
for (ResolveInfo res : listCam) {
final String packageName = res.activityInfo.packageName;
final Intent intent = new Intent(captureIntent);
intent.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
intent.setPackage(packageName);
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
cameraIntents.add(intent);
}
// Filesystem.
final Intent galleryIntent = new Intent();
galleryIntent.setType("image/*");
galleryIntent.setAction(Intent.ACTION_GET_CONTENT);
// Chooser of filesystem options.
final Intent chooserIntent = Intent.createChooser(galleryIntent, "Select Source");
// Add the camera options.
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, cameraIntents.toArray(new Parcelable[cameraIntents.size()]));
startActivityForResult(chooserIntent, REQUEST_TAKE_PHOTO);
}
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
if (requestCode == REQUEST_TAKE_PHOTO) {
final boolean isCamera;
if (data == null) {
isCamera = true;
} else {
final String action = data.getAction();
if (action == null) {
isCamera = false;
} else {
isCamera = action.equals(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
}
}
Uri selectedImageUri;
if (isCamera) {
selectedImageUri = outputFileUri;
} else {
selectedImageUri = data == null ? null : data.getData();
}
// mainView.setImageURI(selectedImageUri);
// Log.d("Before adding", selectedImageUri.toString());
happyList.add(selectedImageUri);
// Log.d("Array:", happyList.toString());
}
}
}
最佳答案
首先,建议您在类中存储一个关键常量。主要原因是保持一致并避免拼写错误。
public static final String HAPPY_LIST = "happyList";
现在,每当您保存和恢复时都使用它
其次,我认为这些应该翻转,因为你想放入你保存的东西,然后执行 super 调用所做的任何事情
此外,Uri 对象是可 Parcelable 的,因此请使用适当的方法
@Override
public void onSaveInstanceState (Bundle savedInstanceState) {
savedInstanceState.putParcelableArrayList(HAPPY_LIST, happyList);
super.onSaveInstanceState(savedInstanceState);
}
最后,您可以在 onRestoreInstanceState 或 onCreate 中使用恢复的包,但我认为您不需要同时执行这两种操作。
关于java - 保存和恢复ArrayList,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38807215/