选择具有特定分辨率的图像时应用程序崩溃

时间:2014-12-02 08:05:59

标签: java android image image-resizing

我有一种将图像转换为圆形并将其设置在图像视图中的方法。该方法在大多数情况下都能正常工作,但在选择具有特定分辨率的图像时行为不正确。

方法:

public void decodeImageFile(String imagePath, Matrix m){

        // Will need to do DP to PX algorith herer

        Bitmap bitmap = decodeSampleBitmapFromFile(imagePath, 1024, 1024);
        //bitmap = Bitmap.createScaledBitmap(bitmap, 540, 960, true);
        int w = bitmap.getWidth();
        int h = bitmap.getHeight();

        Log.e("height", ""+h);
        Log.e("width", ""+w);

        //to prevent crashing the app as this is not a legal resolution
//      if (h == 1920 && w == 2160) {
//          bitmap = Bitmap.createScaledBitmap(bitmap, 540, 960, true);
//      }

        // logic to check whether the resulting image has a height or
        // width greater than 0
        if (bitmap.getWidth() > 0 && bitmap.getHeight() > 0) {
            bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), m, true);

            bitmap = ImageController.transferSquare(bitmap);
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
            Base64.encodeToString(baos.toByteArray(), Base64.DEFAULT);
            byteArray = baos.toByteArray();

            bitmap = ImageController.resizeToHighResolutionCircle(bitmap);
            choosePhotoBtn.setBackgroundResource(R.drawable.add_detail_photo_opaq_xhdpi);
            yourPhoto.setImageBitmap(Bitmap.createScaledBitmap(bitmap, yourPhoto.getWidth(), yourPhoto.getHeight(), false));
        }

    }

我已经看到了1080x1920和1920x2160分辨率的崩溃。 1080x1920分辨率的logcat:

12-02 13:26:57.255: D/dalvikvm(28494): GC_FOR_ALLOC freed 14357K, 28% free 37780K/52472K, paused 17ms, total 17ms
12-02 13:26:57.335: E/height(28494): 1080
12-02 13:26:57.335: E/width(28494): 1920
12-02 13:26:57.350: D/dalvikvm(28494): GC_FOR_ALLOC freed 93K, 21% free 41738K/52472K, paused 12ms, total 12ms
12-02 13:26:57.355: I/dalvikvm-heap(28494): Grow heap (frag case) to 46.646MB for 4147216-byte allocation
12-02 13:26:57.365: D/dalvikvm(28494): GC_FOR_ALLOC freed <1K, 19% free 45788K/56524K, paused 11ms, total 11ms
12-02 13:26:57.610: D/dalvikvm(28494): GC_FOR_ALLOC freed 9108K, 27% free 42971K/58508K, paused 14ms, total 14ms
12-02 13:26:57.635: D/dalvikvm(28494): GC_FOR_ALLOC freed 5156K, 22% free 43217K/54748K, paused 15ms, total 15ms
12-02 13:26:57.645: I/dalvikvm-heap(28494): Grow heap (frag case) to 48.585MB for 4665616-byte allocation
12-02 13:26:57.665: D/dalvikvm(28494): GC_FOR_ALLOC freed 0K, 20% free 47773K/59308K, paused 17ms, total 17ms
12-02 13:27:03.610: W/dalvikvm(29085): threadid=12: thread exiting with uncaught exception (group=0x41939c08)
12-02 13:27:03.610: E/AndroidRuntime(29085): FATAL EXCEPTION: Parse.initialize Disk Check & Starting Command Cache
12-02 13:27:03.610: E/AndroidRuntime(29085): Process: com.navitas.studystory, PID: 29085
12-02 13:27:03.610: E/AndroidRuntime(29085): java.lang.SecurityException: Unable to find app for caller android.app.ApplicationThreadProxy@43839f28 (pid=29085) when registering receiver android.content.IIntentReceiver$Stub$Proxy@42c70b60
12-02 13:27:03.610: E/AndroidRuntime(29085):    at android.os.Parcel.readException(Parcel.java:1472)
12-02 13:27:03.610: E/AndroidRuntime(29085):    at android.os.Parcel.readException(Parcel.java:1426)
12-02 13:27:03.610: E/AndroidRuntime(29085):    at android.app.ActivityManagerProxy.registerReceiver(ActivityManagerNative.java:2551)
12-02 13:27:03.610: E/AndroidRuntime(29085):    at android.app.ContextImpl.registerReceiverInternal(ContextImpl.java:1821)
12-02 13:27:03.610: E/AndroidRuntime(29085):    at android.app.ContextImpl.registerReceiver(ContextImpl.java:1789)
12-02 13:27:03.610: E/AndroidRuntime(29085):    at android.app.ContextImpl.registerReceiver(ContextImpl.java:1783)
12-02 13:27:03.610: E/AndroidRuntime(29085):    at android.content.ContextWrapper.registerReceiver(ContextWrapper.java:479)
12-02 13:27:03.610: E/AndroidRuntime(29085):    at com.parse.ConnectivityNotifier.tryToRegisterForNetworkStatusNotifications(ConnectivityNotifier.java:55)
12-02 13:27:03.610: E/AndroidRuntime(29085):    at com.parse.ConnectivityNotifier.addListener(ConnectivityNotifier.java:34)
12-02 13:27:03.610: E/AndroidRuntime(29085):    at com.parse.ParseCommandCache.<init>(ParseCommandCache.java:101)
12-02 13:27:03.610: E/AndroidRuntime(29085):    at com.parse.Parse.getEventuallyQueue(Parse.java:527)
12-02 13:27:03.610: E/AndroidRuntime(29085):    at com.parse.Parse$1.run(Parse.java:126)
12-02 13:27:03.680: W/ApplicationPackageManager(29098): getCSCPackageItemText()
12-02 13:27:03.780: D/dalvikvm(29098): GC_FOR_ALLOC freed 206K, 12% free 17072K/19260K, paused 18ms, total 19ms
12-02 13:27:03.795: I/dalvikvm-heap(29098): Grow heap (frag case) to 25.620MB for 7356976-byte allocation
12-02 13:27:03.815: D/dalvikvm(29098): GC_FOR_ALLOC freed 0K, 9% free 24257K/26448K, paused 17ms, total 17ms
12-02 13:27:03.845: E/Lifecycle(29098): The onCreate() event
12-02 13:27:03.845: E/Lifecycle(29098): The onStart() event
12-02 13:27:03.850: E/Lifecycle(29098): The onResume() event
12-02 13:27:03.940: D/OpenGLRenderer(29098): Enabling debug mode 0
12-02 13:27:33.950: E/Lifecycle(29098): The onPause() event
12-02 13:27:33.955: E/Lifecycle(29098): The onStop() event

请告诉我哪里出错了?什么是小姐?

2 个答案:

答案 0 :(得分:0)

将android:largeHeap =“true”添加到清单中的应用程序标记,以便能够声明更多内存并使用多线程进行繁重的操作。 asynctask是用于短期操作的内置线程类,它是完美的,尽管你的GUI在等待任务完成解码时仍会挂起一段时间。

How to write ASyncTasks

例如,解码器任务。

public class BitmapDecoderTask extends AsyncTask<File, Integer, Bitmap> {

    protected Bitmap doInBackground(File... files) {
        int count = files.length;
        Bitmap fullImage = null;
        for (int i = 0; i < count; i++) {
            fullImage = BitmapFactory.decodeFile(files[i].getAbsolutePath());
            publishProgress((int) ((i / (float) count) * 100));
            // Escape early if cancel() is called
            if (isCancelled()) break;
        }
        return fullImage;
    }

    protected void onProgressUpdate(Integer... progress) {
        //setProgressPercent(progress[0]);
    }

    protected void onPostExecute(Long result) {
        //showDialog("Downloaded " + result + " bytes");
    }
}

之后你可以创建其中一个任务,调用execute on it和get()结果,或者如果是写操作,只需让它运行并在任何时候完成。

请记住回收()您的位图以避免不必要的内存声明。

答案 1 :(得分:0)

创建课程

public class MyUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler {
     @Override
     public void uncaughtException(Thread thread, Throwable ex) {
     if(ex.getClass().equals(OutOfMemoryError.class))
     {
     try {
       android.os.Debug.dumpHprofData("/sdcard/dump.hprof");
     } 
     catch (IOException e) {
       e.printStackTrace();
     }
     }
     ex.printStackTrace();
     }
}

然后将以下代码放在mainActivity

Thread.currentThread().setDefaultUncaughtExceptionHandler(new MyUncaughtExceptionHandler());