Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/219.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
异常处理-Android_Android_Exception Handling - Fatal编程技术网

异常处理-Android

异常处理-Android,android,exception-handling,Android,Exception Handling,我的应用程序有时会因OutOfMemory错误而崩溃。我试图优雅地处理它,而不是让应用程序崩溃。下面是错误的日志,然后是我的try/catch块: 编辑此问题是关于异常处理,而不是有效显示图像。加载时,我正在将图像采样到有效大小。但是,在旧手机上,它仍然可能崩溃,因为用户可以手动将图像添加到活动中。我希望有消息说他们增加了限额,而不是崩溃。谢谢 02-14 09:46:11.833: E/dalvikvm-heap(8495): Out of memory on a 2424016-byte a

我的应用程序有时会因OutOfMemory错误而崩溃。我试图优雅地处理它,而不是让应用程序崩溃。下面是错误的日志,然后是我的try/catch块:

编辑此问题是关于异常处理,而不是有效显示图像。加载时,我正在将图像采样到有效大小。但是,在旧手机上,它仍然可能崩溃,因为用户可以手动将图像添加到活动中。我希望有消息说他们增加了限额,而不是崩溃。谢谢

02-14 09:46:11.833: E/dalvikvm-heap(8495): Out of memory on a 2424016-byte allocation.
02-14 09:46:11.833: I/dalvikvm(8495): "main" prio=5 tid=1 RUNNABLE
02-14 09:46:11.833: I/dalvikvm(8495):   | group="main" sCount=0 dsCount=0 obj=0x40fc3508 self=0x40fb2ff8
02-14 09:46:11.833: I/dalvikvm(8495):   | sysTid=8495 nice=0 sched=0/0 cgrp=apps handle=1074818864
02-14 09:46:11.838: I/dalvikvm(8495):   | schedstat=( 10854840575 3262089934 15014 ) utm=971 stm=113 core=1
02-14 09:46:11.838: I/dalvikvm(8495):   at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
02-14 09:46:11.838: I/dalvikvm(8495):   at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:625)
02-14 09:46:11.838: I/dalvikvm(8495):   at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:478)
02-14 09:46:11.838: I/dalvikvm(8495):   at android.graphics.BitmapFactory.decodeResource(BitmapFactory.java:501)
02-14 09:46:11.838: I/dalvikvm(8495):   at com.btf271.imagehelper.ImageHelper.decodeSampledBitmapFromResource(ImageHelper.java:218)
02-14 09:46:11.838: I/dalvikvm(8495):   at com.btf271.multitouchimages.MultitouchImagesView$Img.load(MultitouchImagesView.java:285)
02-14 09:46:11.838: I/dalvikvm(8495):   at com.btf271.multitouchimages.MultitouchImagesView.loadImages(MultitouchImagesView.java:134)
02-14 09:46:11.838: I/dalvikvm(8495):   at com.btf271.fashionassistant.DressingRoomActivity.onResume(DressingRoomActivity.java:125)
02-14 09:46:11.843: I/dalvikvm(8495):   at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1199)
02-14 09:46:11.843: I/dalvikvm(8495):   at android.app.Activity.performResume(Activity.java:5280)
02-14 09:46:11.843: I/dalvikvm(8495):   at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2629)
02-14 09:46:11.843: I/dalvikvm(8495):   at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2667)
02-14 09:46:11.843: I/dalvikvm(8495):   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1279)
02-14 09:46:11.843: I/dalvikvm(8495):   at android.os.Handler.dispatchMessage(Handler.java:99)
02-14 09:46:11.843: I/dalvikvm(8495):   at android.os.Looper.loop(Looper.java:137)
02-14 09:46:11.843: I/dalvikvm(8495):   at android.app.ActivityThread.main(ActivityThread.java:4921)
02-14 09:46:11.843: I/dalvikvm(8495):   at java.lang.reflect.Method.invokeNative(Native Method)
02-14 09:46:11.843: I/dalvikvm(8495):   at java.lang.reflect.Method.invoke(Method.java:511)
02-14 09:46:11.843: I/dalvikvm(8495):   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1027)
02-14 09:46:11.843: I/dalvikvm(8495):   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:794)
02-14 09:46:11.843: I/dalvikvm(8495):   at dalvik.system.NativeStart.main(Native Method)
02-14 09:46:11.843: A/libc(8495): Fatal signal 11 (SIGSEGV) at 0x0000bed8 (code=1), thread 8495 (ashionassistant)
02-14 09:46:22.023: I/ActivityThread(8849): Pub com.btf271.ImageHelper.contentproviders.media: com.btf271.imagehelper.MediaContentProvider
导致错误的方法:MultitouchImagesView.loadImagesMultitouchImagesView.java:134:

/** Called by activity's onResume() method to load the images */
public void loadImages(Context context) {
    Resources res = context.getResources();
    int n = mImages.size();
    for (int i = 0; i < n; i++){
        try{
        mImages.get(i).load(res);
        }
        catch(OutOfMemoryError oom){
            Log.d("out of memory", "out of memory");
        }
        catch( Exception ex) {
            Log.d("general exception", ex.getMessage());
        }
    }
}
NKN的回答解释了为什么它崩溃得很好。那么有解决办法吗

有关该应用程序的更多信息。用户每次向活动中添加一个图像,可以添加任意数量的图像。因此,我将在第6张图片处将其关闭,以避免outOfMemory异常。但是,我是否可以在他们每次向活动中添加图像时检查outOfMemory异常,以防一部手机无法处理6个图像?有些手机可以处理30张图像,但有些手机可能只能处理6张左右的图像。

尽管有try/catch块,但它还是会崩溃,因为您的内存已经用完了。你的一些图像正在/正在消耗你剩下的所有内存,当这种情况发生时,尽管你试图处理它,但你没有任何可用内存,所以你的应用程序根本就死掉了


我会删除你的drawable文件夹中的每个图像,然后逐个添加它们,这样你就可以轻松地检测出痛苦的图像并正确地管理它。我建议阅读。

通过定义全局异常handler,尝试从内存中转储应用程序的垃圾

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) {
                Log.d("SD ExceptionHandler", ex.getMessage().toString());
            }
        } else {
            Log.d("SD ExceptionHandler", ex.getMessage().toString());
        }
    }

}
然后在活动的onCreate调用中:

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

您需要在清单中将此标志设置为应用程序属性:

android:largeHeap="true"
因为您的目标是SDK 11或更高版本,所以它应该可以工作

位图占用大量内存,特别是对于像这样的丰富图像 照片。例如,Galaxy Nexus上的相机会拍照 高达2592x1936像素500万像素。如果位图配置 使用的是ARGB_8888,这是Android 2.3之后的默认版本 将此图像加载到内存中大约需要19MB的内存2592*1936*4 字节,立即耗尽某些设备上的每应用程序限制

您的内存不足,因为您没有仔细处理图像。查看以下问题/答案,以更好地了解尝试加载图像时会发生什么情况:

如果你是一个新的开发人员,那么我建议你只使用任何好的库来为你加载部分,否则加载图像会非常困难

Android通用图像加载器:广泛使用的库


毕加索替代图书馆:一行代码就可以帮你完成任务:

谢谢,我已经读了你发布的那一课。我不认为我可以删除图像并逐个添加,因为加载时需要保留很多位置和大小信息。还有其他方法吗?您可以简单地复制一个可绘制文件夹,然后用一个与您要替换的图像同名的1Kb虚拟图像替换每个图像。布局是否加载不正确并不重要,它只是为了调试。如果你一个接一个地替换图像,你会很快看到哪个图像产生了OOM错误。我不确定这是否适用于我的应用程序。我想你可能需要更多关于我的应用程序的信息。我以用户身份将图像手动添加到活动中。用户可以继续添加越来越多的内容,但我会在第6张图片上强制停止。但由于每部手机都不一样,我想在用户每次添加一部手机时检查是否存在异常,以防他们无法添加到6幅图像。在我的情况下,你说的是一种有效的方式吗?谢谢。用户一次添加一个。所以我确实知道是什么导致了异常,所以我想更多的是在其他地方捕捉错误,就像之前一样,这是一种更少的工作。如果可能的话。谢谢,谢谢。这个代码对我来说有点陌生,因为我是一名学生。我会逐字复制这个,甚至/sdcard/dump.hprof吗?这段代码是否从内存中转储垃圾,因此,在我的每个活动的onCreate中使用它会很好?谢谢!我得到这个警告:不要硬编码/SD卡/;改用Environment.getExternalStorageDirectory.getPath。我应该那样做吗?是的,那是个更好的主意。但这只是一个警告;谢谢我得到另一个警告,当我调用它时,应该以静态方式访问它。我最初有Thread.currentT。。。。然后我把它改为Thread.currentThread;Thread.SetDefaultUncaughtExceptionHandler新建MyUncaughtExceptionHandler;根据Eclipse的建议,这有助于解决bug吗?人们一直认为我没有有效地显示位图,但我已经阅读了关于Android开发人员培训的文章,并实现了这些技术。即使使用毕加索,我也可以在用户添加大量图像后引发异常
. 我只需要异常处理,让他们知道什么时候他们已经添加了图像的限制。任何电话都会在某个时候崩溃。Thanks@user3164083正如你所知,我使用Android Universal Image Loader在一次活动中处理了1000多张照片,而且没有崩溃。这将是一个gridview,我在这个应用程序中没有任何库。我需要这些图像在这个活动中一直保存在内存中,因为它不是一个grdview,它们永远不会离开屏幕。很多不同的故事。你可能会发现这是有用的感谢,这是有用的。我认为在我的场景中,捕捉错误是可以的,例如,当抛出错误时——当用户添加了他们的图像限制时,不要添加最后一个会使应用程序崩溃的图像。也许毕加索会有所帮助,但我不明白为什么,当我已经在对图像进行采样时,我无法回收它们或做类似的事情,因为它们留在屏幕上,所以只能进行采样。