我有三个全屏周视图,一次加载(上一个,下一个,当前).每周视图有7列(一周中的每一天),具有可绘制的背景.
我的可绘制资源背景是
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Grey border on left and right --><item><shape><solid android:color="#999"/></shape></item>
<!-- White background (.5pt to not cover border) --><item android:left=".5pt" android:right=".5pt"><shape>solid android:color="#FFF"/></shape></item>
<!-- Image that repeats to make a grid --><item android:left=".5pt" android:right=".5pt"><bitmap android:src="@drawable/grid" android:tileMode="repeat" android:gravity="center" /></item>
<!-- Times that align left. (12AM, 1AM, etc) --><item android:left="1pt" android:right=".5pt"><bitmap android:src="@drawable/grid_times" android:gravity="top|left|clip_horizontal" /></item>
</layer-list>
Run Code Online (Sandbox Code Playgroud)
出于某种原因,如果我有三组七个在彼此前面,只有前面(可见一个)获得重复图像(实际上是一个gif).如果我将前面移开,你可以看到其他人没有得到重复的图像
布局是RelativeLayout,其中包含三个子类RelativeLayout.这三个子类彼此相同,并且覆盖dispatchTouchEvent允许它们被拖动.它们从彼此顶部开始,因此只有前面的一个可见.它们几乎完全相同,只是其中一个在顶部(首先).
这是android的顶视图
' first '
' second '
' third '
| |#<-- The android screen boundaries. Only …Run Code Online (Sandbox Code Playgroud) 在Android上使用AFAIK时,建议将Bitmap对象引用为WeakReferences以避免内存泄漏.当不再保留位图对象的硬引用时,垃圾收集器将自动收集它.
现在,如果我理解正确,必须始终调用Bitmap.recycle()方法来释放Bitmap.我认为这是因为Bitmap对象具有特殊的内存管理.
那是对的吗?
如果这是真的,当使用WeakReferences时,必须存在内存泄漏,因为在释放WeakReferences时永远不会调用Bitmap.recycle().或者,不知何故,WeakReferences是否足以避免内存泄漏?
谢谢
android garbage-collection memory-leaks weak-references bitmap
我正在尝试学习如何在android中制作一个动画精灵,并且无法弄清楚如何组织我的位图.我有一个我的角色的精灵表向右走:一个五位副本的位图,在一个步行循环中等间距(每45px).
我计划通过以下方式一次绘制我的精灵表位图的一小部分来绘制每个帧:
Rect sourceRect = new Rect(0, 0, 45, 75);
canvas.drawBitmap(spriteSheetBitmap, sourceRect, new Rect(0, 0, 45, 75), null);
Run Code Online (Sandbox Code Playgroud)
然后对于下一帧,将"sourceRect.x"递增45,然后重绘,依此类推.
但是,我现在还不确定如何让我的精灵走向左边.我原本以为我可以只镜像我正在绘制的矩形以获得翻转图片.就像是:
sourceRect = new Rect(45, 0, 0, 75);
Run Code Online (Sandbox Code Playgroud)
这似乎不起作用(不确定这里实际发生了什么,但没有任何东西被吸引到我的表面).
在线搜索,似乎我应该复制我的原始位图,用变换矩阵镜像它,然后在向左走时使用该位图进行绘制.但是我也发现了一些实现,其中许多较小的位图对象是从原始精灵表中创建的,存储(并为镜像运动转换),然后根据需要使用.
所以我想知道在这种情况下最好的是什么,或者确实存在任何差异(性能/内存):
方法1:加载我的原始精灵表,制作一个新的位图实例,镜像它,然后计算所有的矩形并使用那些+两个整张纸来绘制(诚然,有一些额外的位图空间,其中未使用精灵表) .
方法2:在我的原始精灵表中加载,为每个帧创建一个新的两个位图对象(1个镜像,1个正常)并存储要从中绘制的对象.
方法3:其他更好的方法?
我使用MetadataRetriever从视频中提取帧,并将所有图像存储在一个ArrayList<Bitmap>.我想将它们全部存储在SD卡上(仅用于测试目的).
但是当我从模拟器中取出一个文件夹并查看保存的图像时,所有图像都只是视频的第一帧.
这就是我从视频中提取帧的方法:
File videoFile=new File(Environment.getExternalStorageDirectory().getAbsolutePath()+"/videos","sample_mpeg4.mp4");
Uri videoFileUri=Uri.parse(videoFile.toString());
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
retriever.setDataSource(videoFile.getAbsolutePath());
ArrayList<Bitmap> rev=new ArrayList<Bitmap>();
//Create a new Media Player
MediaPlayer mp = MediaPlayer.create(getBaseContext(), videoFileUri);
int millis = mp.getDuration();
for(int i=0;i<millis;i+=100){
Bitmap bitmap=retriever.getFrameAtTime(i,OPTION_CLOSEST_SYNC);
rev.add(bitmap);
}
Run Code Online (Sandbox Code Playgroud)
这就是我如何保存它们(我正在调用此方法并传递位图ArrayList):
public void saveFrames(ArrayList<Bitmap> saveBitmapList) throws IOException{
Random r = new Random();
int folder_id = r.nextInt(1000) + 1;
String folder = Environment.getExternalStorageDirectory()+"/videos/frames/"+folder_id+"/";
File saveFolder=new File(folder);
if(!saveFolder.exists()){
saveFolder.mkdirs();
}
int i=1;
for (Bitmap b : saveBitmapList){
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
b.compress(Bitmap.CompressFormat.JPEG, …Run Code Online (Sandbox Code Playgroud) OutOfMemoryErrors即使在确保我的所有位图都已正确缩放之后,我也一直面临着一些烦人的问题.事实上,这个问题似乎与Bitmaps根本没有关系,但我可能错了.
出于测试和错误隔离的目的,我一直在使用导航抽屉(不使用后退按钮)在两个活动之间切换(让我们称之为Main和List).我可以在DDMS中看到每次返回时分配的内存增加大约180 KB.
我已完成内存转储并使用eclipse MAT分析3个不同的时间点:



我怀疑内存泄漏,但我无法找到原因.根据内存转储,它看起来像是"剩余"并且java.lang.FinalizerReference不断增加.这个问题的用户在FinalizerReferences他的内存转储中也有很多,但答案还不是很清楚.
我在最后一个时间点提出的泄漏嫌疑人报告并不是很有帮助,因为它怀疑android.content.res.Resources并且android.graphics.Bitmap随着时间的推移似乎没有增长:

在其中一份报告中(遗憾的是,这里没有),我看到13个被android.widget.ListView指出为潜在泄密嫌疑人的实例.
这些内存增加发生在活动之间的任何转换(不仅仅是本例中使用的Main和List).
如何找到(非显而易见的?)内存泄漏?我一直在摸不着头脑,所以任何帮助和提示都会很棒.
位图(@ OrhanC1):我已经评论Bitmap了上面提到的两个活动中的任何实例,内存仍在增加.内存转储仍显示一些位图,但我相信它们与资源有关,而不是我分配的实际位图.
关于自定义字体(@erakitin):我正在使用它们,但我使用单例Typeface在我的Application上下文(public class MyApp extends Application)中保留每个字体的单个实例.我已经尝试评论上面提到的两个活动中对字体的任何引用,内存仍然增加.
我不认为我正在泄漏Context(@DigCamara):我没有在这两个活动中持有任何静态引用,我使用Application上下文而不是Activity在适配器中的's.如果我保持相同Activity并进行一些屏幕旋转,则内存不会增加.
基于@ NickT的评论:我可以看到我有两个活动的很多实例.这些内存增加是否只是后端堆栈活动数量增加而不是内存泄漏的结果(虽然操作系统处理的内容显然没有)?如果我使用FLAG_ACTIVITY_REORDER_TO_FRONTintent标志,那么内存只会增加,直到所有不同的活动都被实例化(一次).这个问题很有用:当内存不足时,Android不会从堆栈中查杀活动.
是否可以从内存(byte[]或stream或Bitmap)加载图片而不将其保存到磁盘?
这是我用来将byte[]数组转换为Bitmap:
unsafe
{
fixed (byte* ptr = Misc.ConvertFromUInt32Array(image))
{
Bitmap bmp = new Bitmap(200, 64, 800, PixelFormat.Format32bppRgb, new IntPtr(ptr));
bmp.RotateFlip(RotateFlipType.Rotate180FlipX);
bmp.MakeTransparent(Color.Black);
bmp.Save("test.bmp");
}
}
Run Code Online (Sandbox Code Playgroud)
而不是使用Bmp.save(),我可以把Bitmap图片框放在我的表格上吗?
我一直在编写一个PCX解码器,到目前为止,PCX图像本身解析得很好,但我无法弄清楚如何设置位图的调色板.
我创建了一个像这样的位图:
Bitmap bmp = new Bitmap(width,
height,
stride2,
System.Drawing.Imaging.PixelFormat.Format8bppIndexed,
pixels);
Run Code Online (Sandbox Code Playgroud)
但我似乎无法使用以下方法设置调色板:
for (int i = 0; i < 256; i += 3)
{
Color b = new Color();
b = Color.FromArgb(palette[i], palette[i + 1], palette[i + 2]);
bmp.Palette.Entries.SetValue(b, i);
}
Run Code Online (Sandbox Code Playgroud)
在这个例子中,我已经读完了pcx文件调色板中的每个字节并将它们存储在palette []中.从那里,我用它来设置位图调色板中的条目.如何设置颜色?
即使您已经尝试了一些减少内存使用的方法,捕获OutOfMemoryError是一个好习惯吗?或者我们应该不抓住异常?哪一个更好的做法?
try {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 4;
bitmap = BitmapFactory.decodeFile(file, options);
} catch (OutOfMemoryError e) {
e.printStackTrace();
}
Run Code Online (Sandbox Code Playgroud)
谢谢
我试图将Drawable中的图像附加到电子邮件中(从我的应用程序到Gmail应用程序)
我试过下一个代码:
Intent emailintent2 = new Intent(android.content.Intent.ACTION_SEND_MULTIPLE);
emailintent2.setType("image/*");
emailintent2.putExtra(Intent.EXTRA_EMAIL, emailaddress2);
emailintent2.putExtra(Intent.EXTRA_SUBJECT, CorAsunto);
emailintent2.putExtra(Intent.EXTRA_TEXT, message2);
ArrayList<Uri> uris = new ArrayList<Uri>();
uris.add(Uri.parse("android.resource://" + getPackageName() + "/" + R.drawable.image1));
uris.add(Uri.parse("android.resource://" + getPackageName() + "/" + R.drawable.image2));
emailintent2.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris);
startActivity(emailintent2);
Run Code Online (Sandbox Code Playgroud)
但是当我将图像附加到电子邮件时,我得到的附件没有扩展名".png",这就是一个大问题.
所以我想在尝试将这个Drawable图像转换为Bitmap时,我认为ArrayList必须是Bitmap.我想我会得到图像在附件中定义的图像.
如果有可能,有人可以告诉我该怎么做吗?转换为位图,添加到Arraylist并附加图像.
如果我说的都错了,有人可以给我一个解决方案吗?我需要将Drawable中的图像附加到带有扩展名(.png)的电子邮件中.