//分配native内存 SkBitmap decodingBitmap; if (!decodingBitmap.setInfo(bitmapInfo) || !decodingBitmap.tryAllocPixels(decodeAllocator)) { // SkAndroidCodec should recommend a valid SkImageInfo, so setInfo() // should only only fail if the calculated value for rowBytes is too // large. // tryAllocPixels() can fail due to OOM on the Java heap, OOM on the // native heap, or the recycled javaBitmap being too small to reuse. return nullptr; }
// Use SkAndroidCodec to perform the decode. SkAndroidCodec::AndroidOptions codecOptions; codecOptions.fZeroInitialized = decodeAllocator == &defaultAllocator ? SkCodec::kYes_ZeroInitialized : SkCodec::kNo_ZeroInitialized; codecOptions.fSampleSize = sampleSize;
//调用解码器解码图片,转换的位图信息保存到decodingBitmap.getPixels()得到的地址中 SkCodec::Result result = codec->getAndroidPixels(decodeInfo, decodingBitmap.getPixels(), decodingBitmap.rowBytes(), &codecOptions);
// called from JNI and Bitmap_Delegate. Bitmap(long nativeBitmap, int width, int height, int density, boolean requestPremultiplied, byte[] ninePatchChunk, NinePatch.InsetStruct ninePatchInsets, boolean fromMalloc) { if (nativeBitmap == 0) { thrownew RuntimeException("internal error: native bitmap is 0"); }
//后调用到这个方法 public@NonNullRunnable registerNativeAllocation(@NonNull Object referent, long nativePtr){ if (referent == null) { thrownew IllegalArgumentException("referent is null"); } if (nativePtr == 0) { thrownew IllegalArgumentException("nativePtr is null"); }
CleanerThunk thunk; CleanerRunner result; try { thunk = new CleanerThunk();//被回收时执行clean的Runnable Cleaner cleaner = Cleaner.create(referent, thunk); result = new CleanerRunner(cleaner);//返回给调用方的Runnable,用于调用方主动执行clean registerNativeAllocation(this.size); } catch (VirtualMachineError vme /* probably OutOfMemoryError */) { applyFreeFunction(freeFunction, nativePtr); throw vme; } // Other exceptions are impossible. // Enable the cleaner only after we can no longer throw anything, including OOME. //赋值native对应内存的地址 thunk.setNativePtr(nativePtr); // Ensure that cleaner doesn't get invoked before we enable it. Reference.reachabilityFence(referent); return result; }
// Native memory allocated for the duration of the Bitmap, // if pixel data allocated into native memory, instead of java byte[] privateint mNativeAllocationByteCount;