【问题标题】:Application crashes when selecting image选择图像时应用程序崩溃
【发布时间】:2015-03-07 06:35:23
【问题描述】:

我想询问我正在从我的应用程序的图库中选择一张图片。我用意图在我的应用程序中打开画廊。代码如下:

public static final int PICK_IMAGE = 1;
    Intent intent = new Intent();
    intent.setType("image/*");
    intent.setAction(Intent.ACTION_GET_CONTENT);
    startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_IMAGE);

当我尝试选择大于 1MB 的大图像时。不幸的是它停止了,否则它工作正常。谁能告诉我为什么会这样?

【问题讨论】:

    标签: android android-intent action


    【解决方案1】:

    首先,当您发布与崩溃相关的问题时,最好发布崩溃日志,以便其他人可以准确地帮助您!

    但幸运的是,这是一种非常常见的崩溃形式。这主要是由于 Android 中的OutOfMemoryException,当您使用大图像时。发生崩溃是因为在 Android 中您使用的内存有限,并且您正试图在应用程序中加载大图像。理想情况下,您应该在内存中加载较低分辨率版本的图像。

    开发者网站上有一个特定的部分,Displaying Bitmaps Efficiently,尝试浏览一下,看看是否有帮助。

    【讨论】:

      【解决方案2】:

      在加载大型位图文件时,BitmapFactory 类提供了几种解码方法(decodeByteArray()、decodeFile()、decodeResource() 等)。

      第 1 步

      在解码时将 inJustDecodeBounds 属性设置为 true 可避免内存分配,为位图对象返回 null,但设置 outWidth、outHeight 和 outMimeType。此技术允许您在构建位图(和内存分配)之前读取图像数据的尺寸和类型。 为避免 java.lang.OutOfMemory 异常,请在解码之前检查位图的尺寸。 要告诉解码器对图像进行二次采样,将较小的版本加载到内存中,请在 BitmapFactory.Options 对象中将 inSampleSize 设置为 true。

      例如,分辨率为 2048x1536 的图像使用 inSampleSize 为 4 进行解码会生成大约 512x384 的位图。将其加载到内存中使用 0.75MB 而不是 12MB 的完整图像。

      这是我的代码:

      public void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent) {
              super.onActivityResult(requestCode, resultCode, imageReturnedIntent);
      
              switch (requestCode) {
      
                  case SELECT_PHOTO:
                      Uri imageUri;
                      try {
                           imageUri = imageReturnedIntent.getData();
                      }catch(Exception e){
                          Toast.makeText(getActivity(),"Image Not Found",Toast.LENGTH_SHORT).show();
                          return;
                      }
                      //final InputStream imageStream = getActivity().getContentResolver().openInputStream(imageUri);
                      //final Bitmap selectedImage = BitmapFactory.decodeStream(imageStream);
                      ShrinkBitmapConverter sh = new ShrinkBitmapConverter(getActivity());
                      Bitmap selectedImage = null;
                      try {
                          selectedImage = sh.shrinkBitmap(imageUri,450,350);
                      } catch (Exception e) {
                          Toast.makeText(getActivity(),"Image Not Found",Toast.LENGTH_SHORT).show();
                      }
                      statusImage = ImageConverter.imageToStringConverter(selectedImage);
                      if(statusImage.length()>512000){
                          Toast.makeText(getActivity(),"Image is too big",Toast.LENGTH_LONG).show();
                      }else {
                          postImage.setImageBitmap(selectedImage);
                      }
              }
          }
      

      ImageConverter.java:

      public class ImageConverter {
      
          public static String imageToStringConverter(Bitmap image){
              ByteArrayOutputStream stream = new ByteArrayOutputStream();
              image.compress(Bitmap.CompressFormat.PNG, 100, stream);
              byte[] byteArray = stream.toByteArray();
              String imageToString = Base64.encodeToString(byteArray, Base64.NO_WRAP);
              return imageToString;
          }
      
          public static Bitmap stringToimageConverter(String imageString){
              byte[] stringTobyte = Base64.decode(imageString, Base64.NO_WRAP);
              Bitmap bmp = BitmapFactory.decodeByteArray(stringTobyte, 0, stringTobyte.length);
              return bmp;
          }
      
      }
      

      ShrinkBitmapConverter.java:

      public class ShrinkBitmapConverter {
          Context context;
          public ShrinkBitmapConverter(Context c){
              context=c;
          }
      
          public Bitmap shrinkBitmap(Uri uri,int width,int height) throws FileNotFoundException {
      
              BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();
              bmpFactoryOptions.inJustDecodeBounds = true;
      
              Bitmap bitmap = null;;
              try {
                  bitmap = BitmapFactory.decodeStream(context.getContentResolver().openInputStream(uri),null,bmpFactoryOptions);
      
                  int heightRatio = (int)Math.ceil(bmpFactoryOptions.outHeight/(float)height);
                  int widthRatio = (int)Math.ceil(bmpFactoryOptions.outWidth/(float)width);
      
                  if (heightRatio > 1 || widthRatio > 1)
                  {
                      if (heightRatio > widthRatio)
                      {
                          bmpFactoryOptions.inSampleSize = heightRatio;
                      } else {
                          bmpFactoryOptions.inSampleSize = widthRatio;
                      }
                  }
      
                  bmpFactoryOptions.inJustDecodeBounds = false;
                  bitmap = BitmapFactory.decodeStream(context.getContentResolver().openInputStream(uri),null,bmpFactoryOptions);
      
              } catch (Exception e) {
      
                  Toast.makeText(context,"Image Not Found",Toast.LENGTH_SHORT).show();
              }
      
              return bitmap;
          }
      }
      

      请阅读此链接了解详情。 http://developer.android.com/training/displaying-bitmaps/load-bitmap.html

      【讨论】:

      • 位图位图 = BitmapFactory.decodeFile(path, optionsImage);
      • code optionsImage.inSampleSize = calculateInSampleSize(optionsImage, 160, 160); codeBitmap bitmap = BitmapFactory.decodeFile(path, optionsImage);
      • 我认为您不需要使用 decodeFile。如果您从图库中使用它,您可能必须使用 decodeStream。我已经编辑了我的代码。不要只是复制代码。试着理解并使用你需要的部分代码。Chill..
      • 我只是复制了返回样本大小的方法..因为我在base64中编码图像,我没有复制整个代码
      • 我已经编辑了我的代码。它不会给出空指针异常。我已经处理了。
      【解决方案3】:

      只需将此行添加到应用程序下的清单中即可。

      添加这个

      android:hardwareAccelerated="false" android:largeHeap="true"

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-25
        • 2020-05-29
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多