https://feisher.github.io/ScreenAdapter/
根据我多年的开发经验,适配分为三个方向:
1.屏幕适配
2.机型适配
3.版本适配(Android系统适配)
为什么要适配:
IOS系统和Android系统的区别:
- 用IOS系统公司只有一家苹果;
- Android开源,源码是公开,系统随便用,Android系统公司:小米,华为,OPP,魅族,锤子,
Android很严重的问题:碎片化严重
( 屏幕,机型系统(小米的MUI,华为EUI....),系统版本( 5.0,6.0,7.0,8.0) )
- 屏幕碎片化:UI界面变形,不好看
- 机型的碎片:有一个APP你转到三星手机,没有问题,运行正常,但是你转到华为手机,一运行就闪退
比如:你打开相机原生的API,xxxx,小米打开相机API方法就变了,YYYY报一个方法找不到异常
3.系统版本碎片化:V4,V7,V13的兼容包
屏幕适配:(为了实现我们的手机屏幕的完美适配:)
1.图片适配
2.dimens适配
3.布局layout适配
4.java代码适配
5.权重适配
6.百分比适配(鸿洋的一个思路 , autoLayout,但是有问题,创造ScreenAdapter )
图片适配:dp,dip,px,sp,屏幕分辨率,屏幕尺寸,(.9图适配)
- dp(dip,dpi)密度( 单位只有咱们Android有,IOS的人不懂 ):屏幕每一英寸存在的像素密度
- px:像素(你的像素点分布的越密集,是不是就可以把一张图片的质量显示更好)
- sp,:描述字体的单位,谷歌推荐使用12sp以上的,通常可以用12sp,14sp,18sp,22sp,这是谷歌推荐,为了避免精度的损失,不用奇数和小数
- 主流的分辨率是前六种:1920×1080、1280×720、1184×720、854×480、960×540、800×480。
- (真实开发中,我们要做的事就是适配当前市场上绝大多数的 Android 屏幕就可以了。)
- 你要制作.9图片.必须PNG格式,哪怕每个给你的是JPG格式,你自己也要改一下后缀名
.9图适配,图片根据我们的内容,自动改变自己的大小
注意:(优化)把适合的图片放到对应的文件夹下,可以节省内存,把高分辨的图片放到低分辨率的文件夹,会导致内存消耗随着差值越大,消耗也就越大如果条件有限,就按照高分辨的切一套图,放到高分辨的文件下,就可以极大节省内存
dp与px计算图(mdpi 1dp=1px):
ldpi:1dp=0.75px mdpi:1dp=1px hdpi:1dp=1.5px xhdpi:1dp=2px xxhdpi:1dp=3px xxxhdpi:1dp=4px
Android手机屏幕标准 对应图标尺寸标准 屏幕密度 比例
xxxhdpi 3840*2160 192*192 640 16
xxhdpi 1920*1080 144*144 480 12
xhdpi 1280*720 96*96 320 8
hdpi 480*800 72*72 240 6
mdpi 480*320 48*48 160 4
ldpi 320*240 36*36 120 3
通过dp和px转化操作进行适配(工具类,固定代码,更常用)
public class DensityUtil {/*** 根据手机的分辨率从 dip 的单位 转成为 px(像素)*/public static int dip2px(Context context, float dpValue) {final float scale = context.getResources().getDisplayMetrics().density; //获取手机的屏幕的密度return (int) (dpValue * scale + 0.5f);}/*** 根据手机的分辨率从 px(像素) 的单位 转成为 dp*/public static int px2dip(Context context, float pxValue) {final float scale = context.getResources().getDisplayMetrics().density;return (int) (pxValue / scale + 0.5f);}}
版本适配:
我们在开发APP的时候也要注意到系统的问题,Android6.0动态权限
问题原因:
Android P版 谷歌在改进系统稳定性的措施上又增加了新的限制, 即应用程序引用非SDK接口,无论采用直接、反射、JNI获取等手段都将受到限制。
详细原因:http://baijiahao.baidu.com/s?id=1596298004755001784&wfr=spider&for=pc
因为我们项目使用的是插件化框架,所以项目中的context是通过反射来通过ContextImpl获取,但是因为P版本加了限制,所以导致反射找不到相对应的方法,从而获取不到context,导致出现了一个空指针异常,使项目无法打开
ContextImpl源码解析:https://blog.csdn.net/dongxianfei/article/details/54632423
解决方案:
华为给出的解决方案有三种
1.向谷歌申请加入灰名单(能量不够,可行性太小)
2.加入华为的白名单(在华为系统正常运行,但是在其他手机系统上无法正常运行)
3.重构代码,不使用当前的插件化框架(代价太大,工作量太大)
以及我在网上找到的三个方案:
https://blog.csdn.net/qq_31391977/article/details/79918689
当前采用的方案是第二种
机型适配:
按照手机的品牌去适配