大多数时候,在Android上获取OOM是由于使用了太多位图和/或创建大位图.
最近我决定试用JNI,以便通过将数据本身存储在JNI端来避免OOM.
在与JNI搞砸了一段时间后,我在SO上创建了一些帖子,寻求帮助并分享我的知识,现在我决定与你分享更多代码.如果有人有兴趣阅读调查结果或做出贡献,这里有帖子:
这一次,我添加了存储,恢复,裁剪和旋转位图的功能.它应该很容易添加更多选项,如果其他人在这里将自己的代码添加到更有用的功能,我会很高兴.
所以我要展示的代码实际上是合并了我创造的所有东西.
Bitmap bitmap=BitmapFactory.decodeResource(getResources(),R.drawable.ic_launcher);
final int width=bitmap.getWidth(),height=bitmap.getHeight();
// store the bitmap in the JNI "world"
final JniBitmapHolder bitmapHolder=new JniBitmapHolder(bitmap);
// no need for the bitmap on the java "world", since the operations are done on the JNI "world"
bitmap.recycle();
// crop a center square from the bitmap, from (0.25,0.25) to (0.75,0.75) of the bitmap.
bitmapHolder.cropBitmap(width/4,height/4,width*3/4,height*3/4);
//rotate the bitmap:
bitmapHolder.rotateBitmapCcw90();
//get the output java bitmap , …Run Code Online (Sandbox Code Playgroud) java-native-interface android bitmap out-of-memory android-ndk
我想创建一个旋转的进度图像,并想知道什么是最好的方法.我可以使用动画列表,例如每100毫秒更换12个图像.这很好用,但创建12个图像或每个大小和分辨率是相当繁琐的:
<animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="false">
<item android:drawable="@drawable/ic_loading_grey_on_black_01" android:duration="100" />
<item android:drawable="@drawable/ic_loading_grey_on_black_02" android:duration="100" />
<item android:drawable="@drawable/ic_loading_grey_on_black_03" android:duration="100" />
<item android:drawable="@drawable/ic_loading_grey_on_black_04" android:duration="100" />
<item android:drawable="@drawable/ic_loading_grey_on_black_05" android:duration="100" />
<item android:drawable="@drawable/ic_loading_grey_on_black_06" android:duration="100" />
<item android:drawable="@drawable/ic_loading_grey_on_black_07" android:duration="100" />
<item android:drawable="@drawable/ic_loading_grey_on_black_08" android:duration="100" />
<item android:drawable="@drawable/ic_loading_grey_on_black_09" android:duration="100" />
<item android:drawable="@drawable/ic_loading_grey_on_black_10" android:duration="100" />
<item android:drawable="@drawable/ic_loading_grey_on_black_11" android:duration="100" />
<item android:drawable="@drawable/ic_loading_grey_on_black_12" android:duration="100" />
Run Code Online (Sandbox Code Playgroud)
我想更简单的解决方案是每个分辨率使用一个图像,而是为每个帧旋转它.在平台资源(android-sdk-windows/platforms ...)中,我在文件drawable/search_spinner.xml中找到了一个名为animated-rotate的东西,但是如果我复制代码得到编译错误抱怨android:framesCount和android: frameDuration(Eclipse中的Google API 2.2):
<animated-rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/spinner_black_20"
android:pivotX="50%"
android:pivotY="50%"
android:framesCount="12"
android:frameDuration="100" />
Run Code Online (Sandbox Code Playgroud)
我也尝试过使用重复旋转动画(在动画资源文件夹中使用),但我实际上更喜欢动画列表版本的外观.
解决这个问题的推荐方法是什么?
如何Drawable在绘制资源时从资源中加载?例如,我想绘制一个箭头,并且能够在绘制时将其旋转到面向不同的方向?
任何人都可以告诉我他们是如何使用'RotateDrawable'来处理它是来自代码还是XML或两者兼而有之?关于Drawables动画的文档非常糟糕,动画似乎只适用于图像.我希望能够为所有drawables制作动画.当我试图从XML获取RotateDrawble时只会导致异常.从XML中查找RotateDrawable的正确功能是什么?
非常感谢
Kerubu
我知道可以创建一个Drawable(或Bitmap)的旋转版本,因此(在这里写一下):
@JvmStatic
fun getRotateDrawable(d: Drawable, angle: Int): Drawable {
if (angle % 360 == 0)
return d
return object : LayerDrawable(arrayOf(d)) {
override fun draw(canvas: Canvas) {
canvas.save()
canvas.rotate(angle.toFloat(), (d.bounds.width() / 2).toFloat(), (d.bounds.height() / 2).toFloat())
super.draw(canvas)
canvas.restore()
}
}
}
Run Code Online (Sandbox Code Playgroud)
我想要autoMirrored设置为一些drawable(在我的情况下是VectorDrawable),它将翻转(镜像使得左边是右边,右边是左边,但不影响顶部和底部),以防设备的区域设置是RTL.
作为一个例子(这只是一个例子!),如果你拿一个显示左箭头的drawable,翻转后它将是一个右箭头.
遗憾的是,这只能从API 19获得.
这就是为什么我决定用它制作一个新的Drawable,成为原版的翻版
我发现了一篇很好的文章,在这里使用Matrix 对View做同样的事情.所以我试过这个:
@JvmStatic
fun getMirroredDrawable(d: Drawable): Drawable {
return object : LayerDrawable(arrayOf(d)) {
override fun draw(canvas: Canvas) {
canvas.save()
val matrix = Matrix()
// use this …Run Code Online (Sandbox Code Playgroud) 我有一个齿轮图像,我想连续旋转固定点.
之前我通过在我的Android类中将图像作为ImageView包含并对其应用RotateAnimation来实现此目的.
@InjectView(R.id.gear00) ImageView gear00;
RotateAnimation ra07 = new RotateAnimation(0, 359, 129, 186);
ra07.setDuration(10000);
ra07.setRepeatCount(RotateAnimation.INFINITE);
ra07.setInterpolator(new LinearInterpolator());
gear00.setAnimation(ra07);
Run Code Online (Sandbox Code Playgroud)基本上,我将ImageView注入到类中并应用旋转动画.
但是,我再也没有使用ImageView的奢侈了.我必须使用Bitmap并在画布上旋转它.
我怎样才能在onDraw()方法中完成我之前正在做的事情,并且在画布上连续旋转固定点的位图?
EDIT1:
我尝试了下面提到的一个建议,我的代码看起来有点像下面的内容
在onCreate()中:
Matrix matrix = new Matrix();
matrix.setRotate(10, 100, 200);
Run Code Online (Sandbox Code Playgroud)
然后在onDraw()中(其中gear00Scaled是要在画布上旋转的位图):
canvas.drawBitmap(gear00Scaled,matrix,new Paint());
我尝试的另一种方法包括保存画布,旋转它,然后恢复它:
canvas.save();
canvas.rotate(10);
canvas.drawBitmap(gear00Scaled,100,200,null);
canvas.restore();
似乎都没有工作!