Android 4.3 or later Bitmap 内存占用问题
最近在做到Skia 相关项目时,由于之前编译的so在Android 4.3 版本以后会出现Crash.经过查看源代码发现
SkBitmap->setConfig 参数列表已经发生了改变。包括GraphicsJNI.h 里面的很多函数参数列表也已经发生了改变。
于是就试着各种方法去解决,
解决思路:
1. 使用自己编译的skia.so
问题:GraphicsJNI 相关的也有改变,因此需要使用自己的Graphics.so. 感觉走远了。这样下去的apk将会很庞大,
于是尝试将Graphics.cpp 文件里createBitmap的源码copy出来 自己实现。(应该没问题)
最后自己再去看源码时,发现Android4.3 以后,在分配内存时已经没有进行内存控制了,而且分配内存的函数也不一样了。
V??? or later 的Bitmap.cpp ->Bitmap_creator
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 |
//-----------------------Bitmap_creator------------------------------ GraphicsJNI::allocateJavaPixelRef(env, &bitmap, NULL); //------------------------------------------------------------------------- jbyteArray GraphicsJNI::allocateJavaPixelRef(JNIEnv* env, SkBitmap* bitmap, SkColorTable* ctable) { Sk64 size64 = bitmap->getSize64(); if
(size64.isNeg() || !size64.is32()) { jniThrowException(env, "java/lang/IllegalArgumentException" , "bitmap size exceeds 32bits" ); return
NULL; } size_t
size = size64.get32(); jbyteArray arrayObj = env->NewByteArray(size); if
(arrayObj) { // TODO: make this work without jniGetNonMovableArrayElements jbyte* addr = jniGetNonMovableArrayElements(&env->functions, arrayObj); if
(addr) { SkPixelRef* pr = new
AndroidPixelRef(env, ( void *) addr, size, arrayObj, ctable); bitmap->setPixelRef(pr)->unref(); // since we‘re already allocated, we lockPixels right away // HeapAllocator behaves this way too bitmap->lockPixels(); } } return
arrayObj; } |
<=V2.3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53 |
//-----------------------Bitmap_creator------------------------------ GraphicsJNI::setJavaPixelRef(env, &bitmap, NULL, true ) //------------------------------------------------------------------------- bool
GraphicsJNI::setJavaPixelRef(JNIEnv* env, SkBitmap* bitmap, SkColorTable* ctable, bool
reportSizeToVM) { Sk64 size64 = bitmap->getSize64(); if
(size64.isNeg() || !size64.is32()) { doThrow(env, "java/lang/IllegalArgumentException" , "bitmap size exceeds 32bits" ); return
false ; } size_t
size = size64.get32(); jlong jsize = size; // the VM wants longs for the size if
(reportSizeToVM) { // SkDebugf("-------------- inform VM we‘ve allocated %d bytes\n", size); bool
r = env->CallBooleanMethod(gVMRuntime_singleton, gVMRuntime_trackExternalAllocationMethodID, jsize); if
(GraphicsJNI::hasException(env)) { return
false ; } if
(!r) { LOGE( "VM won‘t let us allocate %zd bytes\n" , size); doThrowOOME(env, "bitmap size exceeds VM budget" ); return
false ; } } // call the version of malloc that returns null on failure void * addr = sk_malloc_flags(size, 0); if
(NULL == addr) { if
(reportSizeToVM) { // SkDebugf("-------------- inform VM we‘re releasing %d bytes which we couldn‘t allocate\n", size); // we didn‘t actually allocate it, so inform the VM env->CallVoidMethod(gVMRuntime_singleton, gVMRuntime_trackExternalFreeMethodID, jsize); if
(!GraphicsJNI::hasException(env)) { doThrowOOME(env, "bitmap size too large for malloc" ); } } return
false ; } SkPixelRef* pr = reportSizeToVM ? new
AndroidPixelRef(env, addr, size, ctable) : new
SkMallocPixelRef(addr, size, ctable); bitmap->setPixelRef(pr)->unref(); // since we‘re already allocated, we lockPixels right away // HeapAllocator behaves this way too bitmap->lockPixels(); return
true ; } |
因此不必担心Android4.3以后加载Bitmap问题
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。