今天在專案上要將 Bitmap 設給 Canvas 時, 發生了以下的錯誤:
Canvas canvas = new Canvas(); File file = new File(TEST_PATH); Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath(), opts); canvas.setBitmap(bitmap);
[Error]
ATAL EXCEPTION: main
java.lang.IllegalStateException
at android.graphics.Canvas.setBitmap (Canvas.java:144)
at com.zl.android.game.LogoImp.onDraw (LogoImp.java:64)
at android.view.View.draw (View.java:6740)
at android.view.ViewGroup.drawChild (ViewGroup.java:1640)
at android.view.ViewGroup.dispatchDraw (ViewGroup.java:1367)
at android.view.View.draw (View.java:6743)
at android.widget.FrameLayout.draw (FrameLayout.java:352)
at android.view.ViewGroup.drawChild (ViewGroup.java:1640)
at android.view.ViewGroup.dispatchDraw (ViewGroup.java:1367)
at android.view.ViewGroup.drawChild (ViewGroup.java:1638)
at android.view.ViewGroup.dispatchDraw (ViewGroup.java:1367)
at android.view.View.draw (View.java:6743)
at android.widget.FrameLayout.draw (FrameLayout.java:352)
at com.android.internal.policy.impl.PhoneWindow$DecorView.draw (PhoneWindow.java:1842)
at android.view.ViewRoot.draw (ViewRoot.java:1407)
at android.view.ViewRoot.performTraversals (ViewRoot.java:1163)
at android.view.ViewRoot.handleMessage (ViewRoot.java:1727)
at android.os.Handler.dispatchMessage (Handler.java:99)
at android.os.Looper.loop (Looper.java:123)
at android.app.ActivityThread.main (ActivityThread.java:4627)
at jav a.lang.reflect.Method.invokeNative (Native Method)
at java.lang.reflect.Method.invoke (Method.java:521)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:868)
at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:626)
at dalvik.system.NativeStart.main (Native Method)
後來研究了一下發現, Canvas 的 setBitmap(Bitmap bitmap) 有一段是這麼寫的:
if (!bitmap.isMutable()) {
throw new IllegalStateException();
}
如果這個 Bitmap 不能被改變, 就不能設定給 Canvas
所以可以用以下方法來處理:
(1) 複製一份可變性的 bitmap
Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath()).copy(Config.ARGB_4444, true); canvas.setBitmap(bitmap);
(2) 設定 Bitmap option 參數
BitmapFactory.Options opts = new BitmapFactory.Options(); opts.inMutable=true; Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath(), opts); canvas.setBitmap(bitmap);
後來是用 (2) 方法來處理, 因為除了 inMutable 參數外, 我還有其他參數也要設 XD