我需要获取View
. 我尝试了两种方法来完成这项工作。不幸的是,两者都会导致相同的错误。
这是日志:
java.lang.IllegalArgumentException: Software rendering doesn't support hardware bitmaps
at android.graphics.BaseCanvas.null onHwBitmapInSwMode(null)(BaseCanvas.java:550)
at android.graphics.BaseCanvas.null throwIfHwBitmapInSwMode(null)(BaseCanvas.java:557)
at android.graphics.BaseCanvas.null throwIfCannotDraw(null)(BaseCanvas.java:69)
at android.graphics.BaseCanvas.null drawBitmap(null)(BaseCanvas.java:127)
at android.graphics.Canvas.null drawBitmap(null)(Canvas.java:1504)
at android.graphics.drawable.BitmapDrawable.null draw(null)(BitmapDrawable.java:545)
at android.widget.ImageView.null onDraw(null)(ImageView.java:1355)
at android.view.View.null draw(null)(View.java:20248)
at android.view.View.null draw(null)(View.java:20118)
at android.view.ViewGroup.null drawChild(null)(ViewGroup.java:4336)
at android.view.ViewGroup.null dispatchDraw(null)(ViewGroup.java:4115)
at android.view.ViewOverlay$OverlayViewGroup.null dispatchDraw(null)(ViewOverlay.java:251)
at android.view.View.null draw(null)(View.java:20251)
at android.view.View.null buildDrawingCacheImpl(null)(View.java:19516)
at android.view.View.null buildDrawingCache(null)(View.java:19379)
at android.view.View.null getDrawingCache(null)(View.java:19215)
at android.view.View.null getDrawingCache(null)(View.java:19166)
at com.omnipotent.free.videodownloader.pro.utils.ViewUtils.android.graphics.Bitmap captureView(android.view.View)(ViewUtils.java:70)
at com.omnipotent.free.videodownloader.pro.ui.main.MainActivity.com.omnipotent.free.videodownloader.pro.data.bean.TabBean getCurrentTabsData()(MainActivity.java:325)
at com.omnipotent.free.videodownloader.pro.ui.main.MainActivity.com.omnipotent.free.videodownloader.pro.data.bean.TabBean access$getCurrentTabsData(com.omnipotent.free.videodownloader.pro.ui.main.MainActivity)(MainActivity.java:84)
at com.omnipotent.free.videodownloader.pro.ui.main.MainActivity$onAddTab$1.void run()(MainActivity.java:628)
at android.os.Handler.null handleCallback(null)(Handler.java:873)
at android.os.Handler.null dispatchMessage(null)(Handler.java:99)
at android.os.Looper.null loop(null)(Looper.java:193)
at android.app.ActivityThread.null main(null)(ActivityThread.java:6936)
at java.lang.reflect.Method.null invoke(null)(Method.java)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.null run(null)(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.null main(null)(ZygoteInit.java:870)
Run Code Online (Sandbox Code Playgroud)
我仔细检查了代码,并在网上查找了相关文章。然而,我还没有解决它,这真的让我感到沮丧。这个bug只发生在android O之上。
以下是我尝试过的两种方法:
方法一:
java.lang.IllegalArgumentException: Software rendering doesn't support hardware bitmaps
at android.graphics.BaseCanvas.null onHwBitmapInSwMode(null)(BaseCanvas.java:550)
at android.graphics.BaseCanvas.null throwIfHwBitmapInSwMode(null)(BaseCanvas.java:557)
at android.graphics.BaseCanvas.null throwIfCannotDraw(null)(BaseCanvas.java:69)
at android.graphics.BaseCanvas.null drawBitmap(null)(BaseCanvas.java:127)
at android.graphics.Canvas.null drawBitmap(null)(Canvas.java:1504)
at android.graphics.drawable.BitmapDrawable.null draw(null)(BitmapDrawable.java:545)
at android.widget.ImageView.null onDraw(null)(ImageView.java:1355)
at android.view.View.null draw(null)(View.java:20248)
at android.view.View.null draw(null)(View.java:20118)
at android.view.ViewGroup.null drawChild(null)(ViewGroup.java:4336)
at android.view.ViewGroup.null dispatchDraw(null)(ViewGroup.java:4115)
at android.view.ViewOverlay$OverlayViewGroup.null dispatchDraw(null)(ViewOverlay.java:251)
at android.view.View.null draw(null)(View.java:20251)
at android.view.View.null buildDrawingCacheImpl(null)(View.java:19516)
at android.view.View.null buildDrawingCache(null)(View.java:19379)
at android.view.View.null getDrawingCache(null)(View.java:19215)
at android.view.View.null getDrawingCache(null)(View.java:19166)
at com.omnipotent.free.videodownloader.pro.utils.ViewUtils.android.graphics.Bitmap captureView(android.view.View)(ViewUtils.java:70)
at com.omnipotent.free.videodownloader.pro.ui.main.MainActivity.com.omnipotent.free.videodownloader.pro.data.bean.TabBean getCurrentTabsData()(MainActivity.java:325)
at com.omnipotent.free.videodownloader.pro.ui.main.MainActivity.com.omnipotent.free.videodownloader.pro.data.bean.TabBean access$getCurrentTabsData(com.omnipotent.free.videodownloader.pro.ui.main.MainActivity)(MainActivity.java:84)
at com.omnipotent.free.videodownloader.pro.ui.main.MainActivity$onAddTab$1.void run()(MainActivity.java:628)
at android.os.Handler.null handleCallback(null)(Handler.java:873)
at android.os.Handler.null dispatchMessage(null)(Handler.java:99)
at android.os.Looper.null loop(null)(Looper.java:193)
at android.app.ActivityThread.null main(null)(ActivityThread.java:6936)
at java.lang.reflect.Method.null invoke(null)(Method.java)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.null run(null)(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.null main(null)(ZygoteInit.java:870)
Run Code Online (Sandbox Code Playgroud)
方法二:
public static Bitmap captureView(View view) {
Bitmap tBitmap = Bitmap.createBitmap(
view.getWidth(), view.getHeight(), Bitmap.Config.RGB_565);
Canvas canvas = new Canvas(tBitmap);
view.draw(canvas);
canvas.setBitmap(null);
return tBitmap;
}
Run Code Online (Sandbox Code Playgroud)
需要提到的是,我已经android:hardwareAccelerated="true"
为我的设置了Activity
,在那里我调用了captureView
方法。
小智 9
您可以尝试将硬件类型位图复制到所需的类型位图,例如:
Bitmap targetBmp = originBmp.copy(Bitmap.Config.ARGB_8888, false);
Run Code Online (Sandbox Code Playgroud)
阅读Glide hardware bitmap docs,找到PixelCopy
class,可能会解决这个bug。
使用PixelCopy
转换view
到Bitmap
更高版本的Android O,并使用下面的Android O.以前的方法
这是我的代码:
fun captureView(view: View, window: Window, bitmapCallback: (Bitmap)->Unit) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
// Above Android O, use PixelCopy
val bitmap = Bitmap.createBitmap(view.width, view.height, Bitmap.Config.ARGB_8888)
val location = IntArray(2)
view.getLocationInWindow(location)
PixelCopy.request(window,
Rect(location[0], location[1], location[0] + view.width, location[1] + view.height),
bitmap,
{
if (it == PixelCopy.SUCCESS) {
bitmapCallback.invoke(bitmap)
}
},
Handler(Looper.getMainLooper()) )
} else {
val tBitmap = Bitmap.createBitmap(
view.width, view.height, Bitmap.Config.RGB_565
)
val canvas = Canvas(tBitmap)
view.draw(canvas)
canvas.setBitmap(null)
bitmapCallback.invoke(tBitmap)
}
}
Run Code Online (Sandbox Code Playgroud)
不足之处是我必须使用回调,我不太喜欢它。
希望它有效。
如果您要转换其中包含 ImageView 的视图,并且使用 Glide 或 Coil 等图像加载库加载其图像,则必须禁用硬件位图。这些库仅将像素数据存储在图形内存中,并且最适合仅将位图绘制到屏幕上的情况。
如果你使用线圈那么你必须做这样的事情
val imageLoader = ImageLoader.Builder(context).allowHardware(false).build()
imageView.load(imageUrl, imageLoader)
Run Code Online (Sandbox Code Playgroud)