我有一个列表视图,每行有几个图像按钮.单击列表行时,将启动新活动.由于相机布局有问题,我不得不建立自己的标签.为结果启动的活动是地图.如果我单击我的按钮启动图像预览(从SD卡加载图像),应用程序将从活动返回到活动返回到listview结果处理程序以重新启动我的新活动,这只是一个图像小部件.
列表视图上的图像预览正在使用光标和ListAdapter.这使得它非常简单,但我不确定如何放置一个经过调整大小的图像(即小的像素大小不像动态src图像按钮那样.所以我只是调整了从手机摄像头下来的图像.
问题是当我试图返回并重新启动第二个活动时,我收到内存不足错误.
这是更好的,因为我还需要对每行中的小部件/元素的属性进行一些更改,因为焦点问题我无法选择带触摸屏的行.(我可以用滚球.)
一旦我在列表视图上禁用了图像,它再次正常工作.
仅供参考:这就是我的做法:
String[] from = new String[] { DBHelper.KEY_BUSINESSNAME,DBHelper.KEY_ADDRESS,DBHelper.KEY_CITY,DBHelper.KEY_GPSLONG,DBHelper.KEY_GPSLAT,DBHelper.KEY_IMAGEFILENAME + ""};
int[] to = new int[] {R.id.businessname,R.id.address,R.id.city,R.id.gpslong,R.id.gpslat,R.id.imagefilename };
notes = new SimpleCursorAdapter(this, R.layout.notes_row, c, from, to);
setListAdapter(notes);
Run Code Online (Sandbox Code Playgroud)
哪里R.id.imagefilename是ButtonImage.
这是我的LogCat:
01-25 05:05:49.877: ERROR/dalvikvm-heap(3896): 6291456-byte external allocation too large for this process.
01-25 05:05:49.877: ERROR/(3896): VM wont let us allocate 6291456 bytes
01-25 05:05:49.877: ERROR/AndroidRuntime(3896): Uncaught handler: thread main exiting due to …Run Code Online (Sandbox Code Playgroud) 我目前正在努力解决Android平台的奇怪行为 - Bitmap/Java堆内存限制.根据设备的不同,Android会将应用程序开发人员限制为16,24或32 MiB的Java堆空间(或者您可能会在有根电话上找到任意随机值).这可以说是相当小,但相对简单,因为我可以使用以下API测量使用情况:
Runtime rt = Runtime.getRuntime();
long javaBytes = rt.totalMemory() - rt.freeMemory();
long javaLimit = rt.maxMemory();
Run Code Online (Sandbox Code Playgroud)
很容易; 现在为了扭曲.在Android中,除少数例外的位图存储在本机堆中,不计入Java堆.谷歌的一些眼光炯炯,纯粹的开发人员认为这是"糟糕的",并允许开发者获得"超过他们的公平份额".因此,有一个很好的小代码可以计算位图和可能的其他资源所产生的本机内存使用量,并与Java堆相加,如果你去了... java.lang.OutOfMemory. 哎哟
但没什么大不了的.我有很多位图,并且不需要所有这些位图.我可以"分页"一些目前尚未使用的内容:
因此,对于尝试#1,我重构了代码,因此我可以使用try/catch包装每个位图加载:
while(true) {
try {
return BitmapFactory.decodeResource(context.getResources(), android_id, bitmapFactoryOptions);
} catch (java.lang.OutOfMemory e) {
// Do some logging
// Now free some space (the code below is a simplified version of the real thing)
Bitmap victim = selectVictim();
victim.recycle();
System.gc(); // REQUIRED; else, weird behavior ensues
}
}
Run Code Online (Sandbox Code Playgroud)
看,这是一个很好的小日志片段,显示我的代码捕获异常,并回收一些位图:
E/Epic (23221): OUT_OF_MEMORY (caught java.lang.OutOfMemory) I/Epic (23221): ArchPlatform[android].logStats() …
我发布了一个应用程序,其中一个基本功能是允许用户拍照,然后将该照片保存在其外部存储的特定文件夹中.
一切似乎都运行正常,但我现在有两个报告声称在拍照后,点击"完成"退出相机(并返回活动),应用程序被强制关闭,带来用户回到主屏幕.
这发生在Samsung Nexus S和Galaxy Tab上.下面我发布了我的代码,以显示我设置我的意图以及如何在onActivityResult()中处理保存和显示照片.任何关于在点击"完成"退出相机应用程序后可能导致崩溃的指导,将不胜感激!
同样,这似乎在大多数设备上都能正常工作,但我想知道它们是否是一种更有效,更通用的方法.谢谢
我如何解雇相机意图
case ACTION_BAR_CAMERA:
// numbered image name
fileName = "image_" + String.valueOf(numImages) + ".jpg";
output = new File(direct + File.separator + fileName); // create
// output
while (output.exists()) { // while the file exists
numImages++; // increment number of images
fileName = "image_" + String.valueOf(numImages) + ".jpg";
output = new File(outputFolder, fileName);
}
camera = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
uriSavedImage = Uri.fromFile(output); // get Uri of the output
camera.putExtra(MediaStore.EXTRA_OUTPUT, uriSavedImage); //pass in Uri to camera …Run Code Online (Sandbox Code Playgroud) 在我的应用程序中,我从JPEG和PNG文件加载了几个图像.当我将所有这些文件放入assets目录并以这种方式加载时,一切正常:
InputStream stream = getAssets().open(path);
Bitmap bitmap = BitmapFactory.decodeStream(stream, null, null);
stream.close();
return new BitmapDrawable(bitmap);
Run Code Online (Sandbox Code Playgroud)
但是当我尝试从SD卡加载完全相同的图像时,我得到一个OutOfMemory异常!
InputStream stream = new FileInputStream("/mnt/sdcard/mydata/" + path);
Bitmap bitmap = BitmapFactory.decodeStream(stream, null, null);
stream.close();
return new BitmapDrawable(bitmap);
Run Code Online (Sandbox Code Playgroud)
这是我在日志中得到的:
11-05 00:53:31.003: ERROR/dalvikvm-heap(13183): 827200-byte external allocation too large for this process.
11-05 00:53:31.003: ERROR/GraphicsJNI(13183): VM won't let us allocate 827200 bytes
...
11-05 00:53:31.053: ERROR/AndroidRuntime(13183): Caused by: java.lang.OutOfMemoryError: bitmap size exceeds VM budget
11-05 00:53:31.053: ERROR/AndroidRuntime(13183): at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
...
Run Code Online (Sandbox Code Playgroud)
为什么会这样?
更新:在真实设备上尝试了这两个 - 似乎我无法将超过12MB的位图加载到所谓的"外部存储器"(这不是SD卡).
我正在为Android Honeycomb编写一个内存密集型应用程序,并且尽可能地对recycle()未使用的Bitmaps 进行了非常小心的处理.实际上,这对于应用程序来说是必要的,因为Bitmaps不断地循环进出内存.但是,我刚刚实现onConfigurationChanged()了Activity,因此(由于多种原因)我试图将内存释放例程放入其中onStop().
目前我的onStop()方法:
Views来显示默认值Drawable;recycle()对Bitmap以前使用的这些小号View秒;Bitmaps的引用.不幸的是,使用Eclipse内存分析器,它似乎对内存使用没有任何影响.
你可以想象,我已经做了很多努力,用一种名义上垃圾收集的语言来释放资源,我希望能有更多的效果.所以我的问题是:做recycle()什么?它是否实际上触发了垃圾收集,或者系统是否会保留在内存中 - 即使你调用System.gc()-until它感觉需要摆脱某些东西?
NB我知道Bitmaps实际上并没有被保存在常规堆中,但我认为调用recycle()足以确保它们被从本机堆中删除.
答案的一部分
我发现如果一个ImageView包含Bitmap已经被回收的Bitmap数据,那么数据仍会保留在内存中,直到setImageBitmap(null)被调用ImageView.甚至可能是这种情况,如果setImageResource(...)或被setImageDrawable(...)调用(它们是在一个相对较小的九个补丁中加载 - 但是,MAT分析显示这并没有删除Bitmap包含在私有成员中的大数据ImageView).简单地调用此函数onStop()已经从我们的应用程序堆中剔除了大约10MB.显然,这可能不适用于预装的Honeycomb版本的Android.
嗨我正在创建一个关于交通标志的应用程序 交通标志是.png格式.其中一些我在horizontalscrollview中展示.但是当试图打开活动时,我从android市场错误报告中得到了这个错误.这是我的错误报告:
<java.lang.RuntimeException: Unable to start activity ComponentInfo{com.besalti.svenskavagmarken/com.besalti.svenskavagmarken.varningsmarken}: android.view.InflateException: Binary XML file line #645: Error inflating class <unknown>
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1659)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1675)
at android.app.ActivityThread.access$1500(ActivityThread.java:121)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:943)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:130)
at android.app.ActivityThread.main(ActivityThread.java:3701)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:624)
at dalvik.system.NativeStart.main(Native Method)
Caused by: android.view.InflateException: Binary XML file line #645: Error inflating class <unknown>
at android.view.LayoutInflater.createView(LayoutInflater.java:518)
at com.android.internal.policy.impl.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:56)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:568)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:623)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:626)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:626)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:626)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:626)
at android.view.LayoutInflater.inflate(LayoutInflater.java:408)
at android.view.LayoutInflater.inflate(LayoutInflater.java:320)
at android.view.LayoutInflater.inflate(LayoutInflater.java:276)
at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:227) …Run Code Online (Sandbox Code Playgroud) 从实验和阅读其他类似的帖子来看,似乎很难在Android上处理高分辨率图像,因为VM允许分配的内存数量有限.
加载800万像素摄像头图片需要大约20 MB的内存.
我知道简单的解决方案是在加载图像时对图像进行下采样(BitmapFactory提供这样的选项)但我仍然希望以全分辨率处理图像:相机拍摄8MP,为什么我只使用4MP并降低质量.
有谁知道这方面的好的解决方法?
由于虚拟内存堆大小有限,我遇到了内存不足的问题.
这是我从服务器获取位图的代码:
@SuppressWarnings("unchecked")
public class DrawableManager {
@SuppressWarnings("rawtypes")
private final Map drawableMap;
@SuppressWarnings("rawtypes")
private DrawableManager() {
drawableMap = new HashMap();
}
static private DrawableManager _instance;
static public DrawableManager getInstance() {
if(_instance == null) {
_instance = new DrawableManager();
}
return _instance;
}
public Bitmap fetchBitmap(final String sURL) {
if(sURL.length() == 0)
return null;
Bitmap bm = (Bitmap) drawableMap.get(sURL);
if(bm != null) {
return bm;
}
byte[] imageData = ThumbImg(sURL);
if(imageData == null)
return null;
if(imageData.length > 0) {
bm = …Run Code Online (Sandbox Code Playgroud) 我收到大图像(png,> 30Mb)并为其创建位图.并获取java.lang.OutOfMemoryError.我试图抓住这样的例外:
try {
Bitmap bmp = BitmapFactory.decodeStream(someStream);
} catch (OutOfMemoryError e) {
;
}
Run Code Online (Sandbox Code Playgroud)
使用2.2 SDK它运作良好.但2.3应用程序失败,未捕获异常.我不明白,为什么?
谢谢!