栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

【案例分享】屏幕适配导致的一个crash的问题。

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【案例分享】屏幕适配导致的一个crash的问题。

问题背景

学而思应用在设备A上必现crash,在B设备上没有问题。A和B是相同的厂商相同的系统版本。

问题原因 首先看crash的日志
 W/Bitmap: Called getByteCount() on a recycle()'d bitmap! This is undefined behavior!
 ? W/System.err: java.lang.IllegalStateException: Can't compress a recycled bitmap
 ? W/System.err:     at android.graphics.Bitmap.checkRecycled(Bitmap.java:514)
 ? W/System.err:     at android.graphics.Bitmap.compress(Bitmap.java:1560)
 ? W/System.err:     at com.tal.xes.app.share.WeixinUtil.bmpToByteArray(WeixinUtil.java:37)
 ? W/System.err:     at com.tal.xes.app.share.XesShareTool.sendWXMessage(XesShareTool.java:364)
 ? W/System.err:     at com.tal.xes.app.share.XesShareTool.shareLink(XesShareTool.java:316)
 ? W/System.err:     at com.xes.jazhanghui.activity.mvp.web.AppWebViewActivity.lambda$showShare$74$AppWebViewActivity(AppWebViewActivity.java:3513)
 ? W/System.err:     at com.xes.jazhanghui.activity.mvp.web.-$$Lambda$AppWebViewActivity$ky7U6HBCmrioBHyzGwtb6oeVh-8.onClick(Unknown Source:2)
 ? W/System.err:     at com.tal.xes.app.share.XesShareTool$4.onClick(XesShareTool.java:513)
 ? W/System.err:     at android.view.View.performClick(View.java:7603)
 ? W/System.err:     at android.view.View.performClickInternal(View.java:7577)
 ? W/System.err:     at android.view.View.access$3800(View.java:865)
 ? W/System.err:     at android.view.View$PerformClick.run(View.java:29384)
 ? W/System.err:     at android.os.Handler.handleCallback(Handler.java:955)
 ? W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:102)
 ? W/System.err:     at android.os.Looper.loopOnce(Looper.java:206)
 ? W/System.err:     at android.os.Looper.loop(Looper.java:296)
 ? W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:8985)
 ? W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
 ? W/System.err:     at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:569)
 ? W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:976)
反编译学而思代码:

代码流程分析:

1。在屏幕密度为400dpi(A)的设备上,Bitmap.createScaledBitmap传入的参数bitmap被decodeResource后的大小已经是目前指定的150,150,createScaledBitmap最终走到createBitmap,createBitmap判断如果传入的长宽大小和source一致,则返回source本身。
2。bitmap被释放。createScaledBitmap=bitmap 导致createScaledBitmap也是被释放的。
3。 createScaledBitmap 也是被释放的。所以导致了第三步的异常。

BitmapFactory.decodeResource

上节中Bitmap source是通过decodeResource加载进来的。

    Bitmap bimap = BitmapFactory.decodeResource(getResources(),R.drawable.ic_launcher_background);

android不同的drawable目录,是针对不同的屏幕密度的。
反编译可以看到原图是在xxhdpi目录下,原始的图片大小是180*180,xxhdpi是针对480屏幕密度的。

BitmapFactory加载图片的时候,有两个重要的属性值。
inTargetDensity当前手机的densityDpi,即当前的手机运行环境的手机密度
**inDensity **是把从资源中读取的density赋值给它,其实就是我们的图片资源所在drawable对应的density,也就是下面表格的对应的值:

举例原始图片在不同屏幕密度上都显示60dp的显示效果:

  • 原始图片180*180 在xxhdpi inDensity = 480 inTargetDensity = 480 1dp=3px 180/3=60dp
  • A设备 150*150 inDensity = 480 inTargetDensity = 400 1dp=2.5px 150/2.5 = 60 显示60DP的尺寸
    每英寸 276.462像素 60dp =150/276.46 = 0.54英寸
  • B设备 105*105 inDensity = 480 inTargetDensity = 280 1dp=1.75px 105/1.75=60 显示60DP的尺寸
    每英寸 195.384像素 60dp =105/195.38 = 0.537英寸

px = dp * (dpi / 160)。
因为原始图片是180*180并且Dpi是480的图片,所以要显示在60dp的长宽高上面。所以在A设备和B设备上也要转换到60DP的长度。
Dpi表示每英寸的像素数,decodeResource也会针对不同的inTargetDensity做相应的大小转换。

所以decodeResource会把图片,进行480/400的缩放,缩放1.2倍。刚好等于150;导致createScaledBitmap时将返回原始的source。进而导致第三步bitmap被释放

屏幕像素密度(dpi)

dpi是 屏幕每英寸显示的像素点数,在同一尺寸下,分辨率越高,屏幕越清晰,dpi越高。得到屏幕像素密度的计算方式如下

dpi不同

屏幕密度不同,即设备分辨率的不同,如在同尺寸的屏幕中,不同分辨率会使屏幕密度不同。如下图示例

在上面两个图中,屏幕的尺寸、比例,都是一样的,但是分辨率是不一样的,这就造成屏幕密度不一样。这样画一条 360px 的直线,在图5中是满屏,在图6中就只有三分之一,在图6中可以显示的内容,在图5中就有可能超过底部边缘,显示不下。这种情况也是造成需要适配的原因。

Android 屏幕适配原因

总结一下适配的 2 个主要原因

1.屏幕像素密度不一样
2.屏幕比例不同(屏幕尺寸不一样)

其实适配,主要是针对这两点进行适配的。理解了屏幕的概念,知道了适配屏幕的原因,这样处理问题就有了方向。下面说说几种官方推荐的主流适配方式,与民间使用比较多的适配方式。

官方推荐适配方式----dp

Dpi表示每英寸的像素数

屏幕适配原理可以参考

https://blog.csdn.net/xiaojinlai123/article/details/103542363?spm=1001.2014.3001.5502

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1028240.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号