Android 使用位图工厂和文件路径显示ImageView,返回NullPointerException

Android 使用位图工厂和文件路径显示ImageView,返回NullPointerException,android,bitmap,imageview,bitmapfactory,Android,Bitmap,Imageview,Bitmapfactory,更新2:问题与onResume和onPause有关。它与位图工厂.decodeFile()无关。问题是,当我去拍照时,会调用onPause,但不会将任何内容保存到SharedReferences,因为还没有任何内容要保存。但是,一旦我从拍照返回,就会调用onResume,并尝试通过从SharedReferences获取适当的值来设置自定义对象的图像路径。由于没有相应的值,它将默认值null应用于imagePath 更新:我的程序的布局是ActivityAhostsFragmentA它承载了下面的

更新2:问题与
onResume
onPause
有关。它与
位图工厂.decodeFile()
无关。问题是,当我去拍照时,会调用
onPause
,但不会将任何内容保存到
SharedReferences
,因为还没有任何内容要保存。但是,一旦我从拍照返回,就会调用
onResume
,并尝试通过从
SharedReferences
获取适当的值来设置自定义对象的图像路径。由于没有相应的值,它将默认值null应用于
imagePath

更新:我的程序的布局是
ActivityA
hosts
FragmentA
它承载了下面的
对话框fragment
。用户按下
FragmentA
中的按钮来拍照,一旦他们拍完照片,在
onActivityResult
中,我将图像路径设置为自定义对象中的字符串变量,并通过调用
Log.d(mObject.getImagePath(),…)来验证它是否存在。

然后,他们可以重新按下相同的图片按钮来查看图像。这就是发生
NullPointerException
的地方。尽管我验证了映像路径是否存在于ActivityResult的
中,但稍后当我尝试访问它时,它将返回null。这就是为什么
BitmapFactory.decodeFile()
返回空值的原因-因为
imagePath
FragmentA
中为空值,当然,当我尝试在
对话框Fragment
中作为额外文件访问它时,它将为空值

任何人都能看到为什么图像路径返回null,即使我验证它存在于
onActivityResult
中并将其分配给我的对象?我不知道为什么会这样。我有一个类似的按钮,用户可以在其中输入文本,然后再次按下按钮以在对话框中查看/编辑该文本。在
onActivityResult
中,我按照相同的步骤将变量分配给我的对象,我没有任何问题

注意:如果您想了解照片的拍摄和保存方式,请参考答案,或按照右侧的链接问题进行操作

imagePath

/data/data/myPackageName/files/myInternalPicturesDir/IMG_20141011_152840.jpg

片段a

    //onCreateView
    mImageButton = (Button) v.findViewById(R.id.imageButton);
    mImageButton.setOnClickListener(new View.OnClickListener()
    {
        public void onClick(View v)
        {
            if (isImageButtonFirstClick)
            {
                Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                imageUri = CameraUtils.getOutputMediaFileUri(CameraUtils.MEDIA_TYPE_IMAGE);
                intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
                startActivityForResult(intent, REQUEST_IMAGE);
            }
            else
            {
                try
                {
                    Log.d("mImageButton onClick", mMyObject.getImagePath());
                    //returns null...
                }
                catch (Exception e)
                {
                    e.printStackTrace();
                }

                FragmentManager fm = getActivity().getSupportFragmentManager();
                InputImageFragment dialog = InputImageFragment.newInstance(mMyObject.getImagePath());
                dialog.show(fm, DIALOG_IMAGE);
            }
        }
    });

...

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
    if (resultCode != Activity.RESULT_OK)
    {
        return;
    }
    ...
    else if (requestCode == REQUEST_IMAGE)
    {
        String pathToInternallyStoredImage = CameraUtils.saveToInternalStorage(getActivity(), imageUri);
        mMyObject.setImagePath(pathToInternallyStoredImage);

        //verify imagePath exists, both return correct path
        Log.d("onActivityResult pathToInternallyStoredImage", pathToInternallyStoredImage);
        Log.d("onActivityResult mMyObject.getImagePath", mMyObject.getImagePath());

        isImageButtonFirstClick = false;
        preferences.edit().putBoolean("isImageButtonFirstClick", isImageButtonFirstClick).commit();
    }
对话框片段

public static InputImageFragment newInstance(String imagePath)
{
    Bundle args = new Bundle();
    args.putSerializable(EXTRA_IMAGEPATH, imagePath);

    InputImageFragment fragment = new InputImageFragment();
    fragment.setArguments(args);

    return fragment;
}

@Override
public Dialog onCreateDialog(Bundle savedInstanceState)
{
    String imagePath = (String) getArguments.getSerializable(EXTRA_IMAGEPATH);

    try
    {
        Log.d("onCreateDialog imagePath", imagePath);
        //returns null...
    }
    catch (Exception e)
    {
        e.printStackTrace();
    }

    View v = getActivity().getLayoutInflater().inflate(R.layout.dialog_input_image, null);

    final ImageView imageView = (ImageView) v.findViewById(R.id.dialogInputImageView);
    Bitmap image = BitmapFactory.decodeFile(imagePath);
    imageView.setImageBitmap(image);

    return new AlertDialog.Builder(getActivity())
            .setView(v)
            .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener()
            {
                @Override
                public void onClick(DialogInterface dialog, int whichButton)
                {
                    dialog.cancel();
                }
            })
            .create();
}
}

这将返回一个
NullPointerException
,从我对
BitmapFactory
的阅读来看,这可能是因为文件名为null或无法解码为位图

10-13 17:10:39.498 5330-5330/myPackageName E/BitmapFactory﹕ 无法解码流:java.lang.NullPointerException

显示该对话框,但它只是一个带有
OK
按钮的空框

我读过类似的问题,问题是
ImageView
本身是空的。我认为这不是问题所在,但下面是XML
对话框\u input\u image
。我尝试过修改XML,我将
ImageView
作为
FrameLayout
的子对象,类似于我看到的其他示例,但我得到了相同的错误

<?xml version="1.0" encoding="utf-8"?>

<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/dialogInputImageView"
    android:orientation="vertical"
    android:scaleType="centerInside"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">
</ImageView>


我刚接触安卓系统,所以我不确定我会错在哪里。感谢您的帮助,谢谢

最好使用
Context
方法
getFilesDir()
从内部存储器中读取,如:

String image path = getFilesDir() .getAbsolutePath(); + "/myInternalPicturesDir/IMG_20141011_152840.jpg";
final ImageView imageView = (ImageView) v.findViewById(R.id.dialogInputImageView);
Bitmap image = BitmapFactory.decodeFile(imagePath);
imageView.setImageBitmap(image);

在将Uri更改为位图之前,首先从下面的代码中获取其路径,然后设置它

..........
Bitmap image = BitmapFactory.decodeFile(getRealPathFromURI(URI));
}

public String getRealPathFromURI(Uri contentURI) throws Exception {
    String result;
    Cursor cursor = context.getContentResolver().query(contentURI, null,
            null, null, null);
    if (cursor == null) { 
        result = contentURI.getPath();
    } else {
        cursor.moveToFirst();
        int idx = cursor
                .getColumnIndex(MediaStore.Images.ImageColumns.DATA);
        result = cursor.getString(idx);
        cursor.close();
    }
    return result;
}

该问题与
BitmapFactory.decodeFile()
无关

问题是,当用户去拍照时,会调用
onPause
。它检查是否存在图像路径,如果存在,则将其保存到
SharedReferences
。用户第一次打开应用程序时,将不存在图像路径,因此不会保存任何内容。拍摄完照片后,调用
onResume
,并尝试从
SharedReferences
检索图像路径,但由于不存在图像路径,因此最终指定了默认值
null
。我一直在使用
boolean
来跟踪何时在
onResume
中检索信息,但更好的解决方案是在尝试检索之前检查值是否为
null

    if (preferences.getString("imagePath", null) != null)
    {
        myObject.setImagePath(preferences.getString("imagePath", null));
    }
假设图像路径已经存在,那么原始代码就可以工作了。但这在第一次就行不通了


我为造成的混乱道歉,并感谢所有试图帮助我的人。虽然问题与您的答案无关(这是我的错),但您的答案仍然很有帮助,我将在继续学习的过程中加以实施。

谢谢您的回答。调用
getActivity().getFilesDir().getAbsolutePath()从我的
对话框片段
返回
/data/data/myPackageName/files
。生成的
imagePath
String
不是仍然相同吗?您可以在帖子中跳过完整的堆栈跟踪吗?当然可以。这就是它显示的全部内容:
10-11 16:35:56.098 31000-31000/myPackageName E/BitmapFactory﹕ 无法解码流:java.lang.NullPointerException
不,每次出错时只有一行。它周围显示的其他东西只有我自己的
Log.d
消息。myInternalPicturesDir是由你的应用程序创建的?其中u
膨胀
onCreateView
@kaushik中的布局,因为这是一个
对话框片段
我不调用
onCreateView
。在返回新的
AlertDialog.Builder时,我在
onCreateDialog
中展开布局,然后调用
setView(v)
。BitmapFactory.decodeFile返回的位图是否为空?为这个异常附加logcat肯定会有帮助。据我所知,问题可能在这里:
String imagePath=(String)getArguments().getSeriali