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问题

Android 4.3 or later Bitmap 内存占用问题,,5-wow.com

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。