我正在对一个应用程序进行压力测试,该应用程序由一系列自定义视图(实际上是3个)组成,这些视图保存在frameLayout中。
虽然一次只举行两次。我有视图1,添加视图2,动画1和2中的动画,然后删除1,反之亦然,如果我通过视图去除bacrd。
每个视图在使用以下方法创建时会加载大量图像数据:
mBmp[background] = BitmapFactory.decodeStream(context.getAssets().open("view1_background.png"));
下面是我的视图切换代码的示例,此切换到下一个视图。
currView.startAnimation(AnimClass.outToLeftAnimation(null));
intView++;
nextView = ViewFactory.getInstance(this, intView, viewInitializer);
mainLayout.addView(nextView, 0);
nextView.startAnimation(AnimClass.inFromRightAnimation(this));
mainLayout.removeViewInLayout(currView);
currView = nextView;
nextView = null;
viewInitializer根据intView调用自定义视图并对其进行实例化,然后使用上述方法加载图像。
问题在于,如果我足够快地切换视图,我可以使它停止跟上(即使我在滑出动画完成之前禁用按钮)并且在几次切换之后我将失去大部分在视图中的图像,最后仍然有一个或两个最小的图像。除了以下消息(该视图中每个图像一个消息)之外,它不会显示任何错误:
01-27 13:52:00.730: DEBUG/skia(23064): ------- imageref_ashmem create failed <(null)> 139264
01-27 13:52:01.011: DEBUG/skia(23064): ------- imageref_ashmem create failed <(null)> 425984
01-27 13:52:01.011: DEBUG/skia(23064): ------- imageref_ashmem create failed <(null)> 1187840
01-27 13:52:01.011: DEBUG/skia(23064): ------- imageref_ashmem create failed <(null)> 139264
01-27 13:52:01.093: DEBUG/skia(23064): ------- imageref_ashmem create failed <(null)> 139264
01-27 13:52:01.128: DEBUG/skia(23064): ------- imageref_ashmem create failed <(null)> 425984
01-27 13:52:01.144: DEBUG/skia(23064): ------- imageref_ashmem create failed <(null)> 1187840
01-27 13:52:01.179: DEBUG/skia(23064): ------- imageref_ashmem create failed <(null)> 139264
01-27 13:52:01.245: DEBUG/skia(23064): ------- imageref_ashmem create failed <(null)> 425984
01-27 13:52:01.261: DEBUG/skia(23064): ------- imageref_ashmem create failed <(null)> 139264
01-27 13:52:01.277: DEBUG/skia(23064): ------- imageref_ashmem create failed <(null)> 1187840
01-27 13:52:01.343: DEBUG/skia(23064): ------- imageref_ashmem create failed <(null)> 139264
01-27 13:52:01.363: DEBUG/skia(23064): ------- imageref_ashmem create failed <(null)> 425984
01-27 13:52:01.409: DEBUG/skia(23064): ------- imageref_ashmem create failed <(null)> 1187840
01-27 13:52:01.429: DEBUG/skia(23064): ------- imageref_ashmem create failed <(null)> 139264
01-27 13:52:01.511: DEBUG/skia(23064): ------- imageref_ashmem create failed <(null)> 139264
如果我切换视图,它在每个视图上都是一样的。在我看来,我的视图切换代码不会在视图被删除时取消分配视图,或者在删除视图后图像(位图)不会被释放。
如果我然后使用意图返回我的主要活动,我会得到以下内容:
Surface E Surface (identity=4810) requestBuffer(0, 00000033) returneda buffer with a null handle
Surface E getBufferLocked(0, 00000033) failed (Out of memory)
Surface E dequeueBuffer failed (Out of memory)
ViewRoot E OutOfResourcesException locking surface
ViewRoot E android.view.Surface$OutOfResourcesException
ViewRoot E at android.view.Surface.lockCanvasNative(Native Method)
ViewRoot E at android.view.Surface.lockCanvas(Surface.java:314)
ViewRoot E at android.view.ViewRoot.draw(ViewRoot.java:1363)
ViewRoot E at android.view.ViewRoot.performTraversals(ViewRoot.java:1172)
ViewRoot E at android.view.ViewRoot.handleMessage(ViewRoot.java:1749)
ViewRoot E at android.os.Handler.dispatchMessage(Handler.java:99)
ViewRoot E at android.os.Looper.loop(Looper.java:123)
ViewRoot E at android.app.ActivityThread.main(ActivityThread.java:4627)
ViewRoot E at java.lang.reflect.Method.invokeNative(Native Method)
ViewRoot E at java.lang.reflect.Method.invoke(Method.java:521)
ViewRoot E at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:871)
ViewRoot E at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:629)
ViewRoot E at dalvik.system.NativeStart.main(Native Method)
任何人都可以建议我可能出错的地方吗?
编辑:未找到确切原因,但我通过在切换视图之间执行垃圾收集来解决问题。
答案 0 :(得分:0)
在使用大量图像时,我更喜欢某种“清理”...在从布局中删除视图之前,您是否尝试取消初始化(回收位图)您加载的图像?
答案 1 :(得分:0)
您是否考虑过使用位图选项导入占用较少图像数据的较小图像?如果您有高分辨率图像(例如相机照片),则无需向用户显示完整的图像分辨率。
在导入位图之前尝试执行此操作
Options options = new Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(context.getAssets().open("view1_background.png"), options);
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
Log.i(getClass().getSimpleName(),
"height: " + options.outHeight +
"\nwidth: " + options.outWidth +
"\nmimetype: " + options.outMimeType +
"\nsample size: " + options.inSampleSize);
options.inJustDecodeBounds = false;
mBmp[background] = BitmapFactory.decodeStream(context.getAssets().open("view1_background.png"));
样本大小由以下因素决定:
public static int calculateInSampleSize( Options options, int reqWidth, int reqHeight)
{
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
while (height / inSampleSize > reqHeight || width / inSampleSize > reqWidth)
{
if (height > width)
{
inSampleSize = height / reqHeight;
if (((double)height % (double)reqHeight) != 0)
{
inSampleSize++;
}
}
else
{
inSampleSize = width / reqWidth;
if (((double)width % (double)reqWidth) != 0)
{
inSampleSize++;
}
}
}
return inSampleSize;
}