Java Android XML位图和OutOfMemoryError

Java Android XML位图和OutOfMemoryError,java,android,out-of-memory,Java,Android,Out Of Memory,我最近在一个android应用程序中遇到了一些OutOfMemory错误,主要是因为我正在加载原始大小的图像(现在我知道这是个坏主意) 我现在正致力于实现方法,根据实际的ImageView大小加载图像的缩小版本,并按照Google开发者指南中的建议缓存它们 该指南很好地说明了我应该如何处理和处理运行时在Java代码中加载的图像,但它遗漏了如何处理布局文件中通过XML定义的图像。 例如,如果我有一个带有预定义图像的ImageView,XML代码将如下所示: <ImageView

我最近在一个android应用程序中遇到了一些OutOfMemory错误,主要是因为我正在加载原始大小的图像(现在我知道这是个坏主意)

我现在正致力于实现方法,根据实际的ImageView大小加载图像的缩小版本,并按照Google开发者指南中的建议缓存它们

该指南很好地说明了我应该如何处理和处理运行时在Java代码中加载的图像,但它遗漏了如何处理布局文件中通过XML定义的图像。 例如,如果我有一个带有预定义图像的ImageView,XML代码将如下所示:

 <ImageView
        android:id="@+id/my_image_id"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/my_image"
         />
显然,对于通过XML定义的图像,还没有这样做。 我是否也必须担心这些图像,或者系统是否为它们处理缩小尺寸?或者我应该完全避免通过XML声明imageview的src吗

提前感谢,,
danijoo

当您从Gallery或Camera中选择图像时,请使用下面的代码缩小图像的大小

       Intent photoPickerIntent = new Intent(
                        Intent.ACTION_PICK,
                                     android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                // photoPickerIntent.setType("image/*");
                photoPickerIntent.putExtra("crop", "true");
                photoPickerIntent.putExtra("outputX", 512);
                photoPickerIntent.putExtra("outputY", 512);
                photoPickerIntent.putExtra("aspectX", 1);
                photoPickerIntent.putExtra("aspectY", 1);
                photoPickerIntent.putExtra("scale", true);
这会将所需大小的图像加载到您的应用程序中,系统不会耗尽内存


您可以询问是否有任何进一步的疑问

当您从可绘图文件夹中设置图像时,android会为您提供帮助。但在这种情况下,你也必须帮助:)。例如,如果您只为drawable mdpi提供一个图像,并且确实在hpdi设备中运行应用程序,android将放大该图像以使其适合屏幕。当然,在这样做之前,它将尝试在drawable hdpi文件夹中查找该图像的hdpi版本。如果您将该图像的hdpi版本提供给drawable hdpi文件夹,它将不会缩放

至于你的OutOfMemoryError,我想你可能只把你的图像放在drawable或者任何一个低dpi的文件夹中,而没有把图像的大版本放在其他高dpi的文件夹中。(hdpi/xhdpi/xxhdpi)

根据文件:

为不同的屏幕密度提供不同的位图可绘制性: 默认情况下,Android会缩放位图可绘制文件(.png、.jpg和.gif文件)和九个补丁可绘制文件(.9.png文件),以便在每个设备上以适当的物理大小进行渲染。例如,如果您的应用程序仅为基线、中等屏幕密度(mdpi)提供位图绘制功能,则系统在高密度屏幕上放大位图绘制功能,在低密度屏幕上缩小位图绘制功能。


我想您会在以下内容中找到更多有用的信息:

此代码没有问题。imageview的预定义src-是正常方式,setImageBitmap工作正常。我认为decodeSampledBitmapFromResource方法或imageView变量中的问题没有正确初始化。上面的代码没有问题。我只是想了解安卓如何处理通过XML直接加载的图像。默认情况下,它们是“大”规模加载还是缩小规模。它们被正确回收了吗?安卓正在做什么很可能取决于版本。我模模糊糊地记得他们对这些(或者可能不是这些而是类似的)事情做了些什么。问题在于decodeSampledBitmapFromResource()方法中。你能发布它吗?你可以看看Android的源代码。看起来它很大程度上依赖于
ImageView
维度,但我还没有找到资源的加载点。答案就在那里我认为danijoos的问题略有不同。对于您的示例,假设您只有xhdpi文件夹中的图片,当然图片具有此类设备所需的分辨率。现在,您希望将此映像用于ldpi设备。如果安卓不缩小规模,这可能意味着该设备内存不足,因为没有可用的ldpi版本。这里有人能测试这个吗?@Baschi我可能错了,但据我所知,android也会处理它:)正如我在文档和我的经验中所发现的:“例如,如果你的应用程序只为基线提供位图绘制,那么中等屏幕密度(mdpi),然后系统在高密度屏幕上放大,在低密度屏幕上缩小。”。你会在@Baschi中找到它,这正是我想知道的!:)@danijoo我可能误解了你的意思,你问的问题和Baschi对我回答的问题一样吗?要回答这个问题,是的,当您在xhpdi文件夹中有图像并且您试图在hdpi/mdpi/ldpi设备上运行该图像时,android确实会缩小该图像。“在低密度屏幕上时,将其缩小。”
       Intent photoPickerIntent = new Intent(
                        Intent.ACTION_PICK,
                                     android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                // photoPickerIntent.setType("image/*");
                photoPickerIntent.putExtra("crop", "true");
                photoPickerIntent.putExtra("outputX", 512);
                photoPickerIntent.putExtra("outputY", 512);
                photoPickerIntent.putExtra("aspectX", 1);
                photoPickerIntent.putExtra("aspectY", 1);
                photoPickerIntent.putExtra("scale", true);