2016-08-20 127 views
-2

我目前在学习Android,这是我的第一个练习应用程序。Android中,适配器的getView中的NullPointerException异常

该应用程序是一个'每日自拍'应用程序。它应该在屏幕上显示项目列表。每个项目应该有一个图像的缩略图和文件名。点击一个项目应该全屏打开图像。操作栏中有一个摄像头图标。点击此应该会打开设备上现有的相机活动。拍摄照片时,应该保存该照片,然后显示在我的应用程序的列表中。

我有以上所有的工作。但是我在这种情况下遇到了问题:我通过我的应用打开相机活动,然后向侧面旋转设备,然后拍照,然后接受照片。因为它试图再次加载我的应用程序,与项目列表,我得到一个NullPointerException。

我已经突破了适配器,并找出了这个问题:适配器中的项目列表在那里,可以说,大小为10.前9个元素已填充且正常,但最后一个元素为空。我没有这个问题,如果我不打开相机时旋转设备。

任何想法解决这个请好吗?我认为与问题相关的代码(我省略了一些东西,比如设置闹钟和上下文菜单,我认为它们在这里不相关?)。

在MainActivity.java:

private File mCurrentPhoto; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     mAdapter = new SelfieListAdapter(getApplicationContext()); 
     setListAdapter(mAdapter); 
     readImages(); 
     getListView().setBackgroundColor(getResources().getColor(R.color.white)); 

     setupAlarm(); 
     registerForContextMenu(getListView()); 
    } 


    private void readImages(){ 
     File dir = getExternalFilesDir(Environment.DIRECTORY_PICTURES); 
     for(File f : dir.listFiles()){ 
      mAdapter.add(f); 
     } 
    } 


    @Override 
    public boolean onOptionsItemSelected(MenuItem menuItem){ 
     if(menuItem.getItemId() == R.id.camera_item){ 
      Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 

      if(intent.resolveActivity(getPackageManager()) != null){ 
       getOutputMediaFile(); //Sets mCurrentPhoto to a new file with a unique name 
       intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(mCurrentPhoto)); 
       startActivityForResult(intent, CAMERA_REQUEST_CODE); 
      } 
     } 
     return true; 
    } 


    @Override 
    public void onActivityResult(int requestCode, int resultCode, Intent data){ 
     if(requestCode == CAMERA_REQUEST_CODE && resultCode == RESULT_OK){ 
      mAdapter.add(mCurrentPhoto); 
     } 
    } 


    private void getOutputMediaFile(){ 
     if(!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){ 
      return; 
     } 

     File mediaStorageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES); 
     if (!mediaStorageDir.exists()){ 
      if (!mediaStorageDir.mkdirs()){ 
       Log.d("DailySelfie", "Failed to create directory"); 
       return; 
      } 
     } 

     String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); 
     mCurrentPhoto = new File(mediaStorageDir.getPath() + File.separator + 
       "IMG_"+ timeStamp + ".jpg"); 
    } 

而且这是在适配器的相关代码:

private static final int THUMBNAIL_WIDTH = 160; 
    private static final int THUMBNAIL_HEIGHT = 120; 
    List<File> mItems = new ArrayList<>(); 
    Context context; 

    public SelfieListAdapter(Context context){ 
     this.context = context; 
    } 

    public void add(File file){ 
     mItems.add(file); 
     notifyDataSetChanged(); 
    } 

    @Override 
    public View getView(int pos, View convertView, ViewGroup parent) { 
     ViewHolder viewHolder; 

     if(convertView == null){ 
      LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
      convertView = inflater.inflate(R.layout.selfie, parent, false); 

      viewHolder = new ViewHolder(); 
      viewHolder.thumbnail = (ImageView) convertView.findViewById(R.id.thumbnail); 
      viewHolder.filename = (TextView) convertView.findViewById(R.id.image_filename); 

      convertView.setTag(viewHolder); 
     } else { 
      viewHolder = (ViewHolder) convertView.getTag(); 
     } 

     File selfie = mItems.get(pos); 

     Bitmap fullImage = BitmapFactory.decodeFile(selfie.getAbsolutePath()); 
     viewHolder.thumbnail.setImageBitmap(
       Bitmap.createScaledBitmap(fullImage, THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT, true)); 

     viewHolder.filename.setText(selfie.getName().split("\\.")[0]); 
     return convertView; 
    } 

    static class ViewHolder{ 
     ImageView thumbnail; 
     TextView filename; 
    } 

我得到的NullPointerException异常是在这条线,因为自拍照为空:

Bitmap fullImage = BitmapFactory.decodeFile(selfie.getAbsolutePath()); 

但仅限于列表中的最后一个元素。谢谢...感谢任何帮助。

并且在旁注中,我在这里做的任何明显不好的做法?

感谢您的任何帮助。

编辑:好的,想想我已经想通了为什么会发生这种情况,但我不知道如何解决它。 当设备倾斜时,我的活动是否被破坏然后重新创建?即使它不是目前的活动?所以mCurrentPhoto是空的,所以我在onActivityResult中向适配器添加一个空值?

我不知道如何解决这个问题。 null意图仍然传递到onActivityResult,所以没有我可以使用的东西。

回答

1

当您旋转CameraActivity并返回到MainActivity时,MainActivity现在也处于新的方向。每当屏幕方向改变时,活动被破坏并重新创建,这就是mCurrentPhoto为空的原因。

解决方案 -

1 - 让您mCurrentPhoto财产法像下面

private File getCurrentPhotoFile(){ 
    return mCurrentPhoto == null ? mCurrentPhoto = new File(mediaStorageDir.getPath() + File.separator + 
      "IMG_"+ timeStamp + ".jpg") : mCurrentPhoto; 
} 

而在你的onActivityResult()使用此

mAdapter.add(getCurrentPhotoFile()); 

或 2 - 请使用用于保存mCurrentPhoto的onSaveInstanceState()回调方法以及onCreate()或onRestoreInstanceState()从包中获取mCurrentPhoto值。

相关问题