最近在做到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问题