如何通过技术优化让 Android 小程序滚动不流畅变得流畅

(转)修改Build.pro 全民学习小优化 让你的手机更加流畅
本帖最后由 xybbonny 于 日 15:56 编辑
undefined 鉴于有个人催着要,undefined 忙中抽空放一个吧。由于我是在制作ROM时用电脑端修改的。而你们正在使用ROM的就用re任务管理器修改吧,感觉自己的老底快被你们榨干了,呵呵。不过算了,大家爽才是真的爽!你们小八用的开心就是我的开心。 为人民服务。。
【教程介绍】: 1、确保手机已经ROOT,并装有RE任务管理器。最好是汉化版的不然不懂英语的伤不起。(一般root了的机子都有,除了刷了我的ROM的。每次都忘记放了汗抱歉) 2、支持眼下的所有官方ROM吧。(42、58、62都可以)。。 (为什么没有CM7 CM9 MIUI呢?亲,那些第三方ROM天天都有作者在想着折腾,就不用咱们操心了,教给他们自己优化吧,当然你认为你能比他做得更好,不管你行不行,反正我是不行,我可是FXP的忠实粉丝,只能膜拜之)
【效果介绍】: 能明显改善你手上官方系统的触控响应,省电,流畅度。 【警告】: 1、本人不对教程负责,本人不对你在操作中自己的失误负责。自己把握,你们已经快把我的老底榨干了,无语之。2、刷前请记得备份原系统,豌豆荚备份也行,难免有些人会因为小错误发生意外,所以事先下个保险。。
Let”s Begin!!
安装建议:如果手机上已经有了英文版,直接安装会提示失败应该。。所以请把原先的卸载了后再安装就可以了。。 再次确认你的手机已经ROOT!第一步:打开re任务管理器(root exeplore)第二步:进入system第三步:将全线只读转为读写(不会就。。。。。。。。)第四步:长按build.pro下滑,选择用文本编辑器打开 第五步:仔细看下面的各种介绍和教程吧。(最好用搜狗,百度等第三方输入法,比较方便吧)
(1)暴力式修改(可以帮你手机改改喔):找到这一栏,###########Updating of the SWVersion ######## 下面的第三行
qro.build.display.id=4.0.2.A.0.62(42/58)
你们用官方固件的一般显示的是这些。(对应的就是手机设置里关于手机里显示的版本号) (只需修改“=”后面的内容).
你可以将其修改成ro.build.display.id=LOVE ROM FOR MY Baby(小名自己打)
就比如我的第一弹ROM就改成的是ro.build.display.id=Present Gfan Wang For YOYO ROM#1
所以我的ROM里版本信息显示的就是它了。。 懂了吧。。
这些在你们学会了做ROM后可以给自己的爱人做一款,或者好朋友做。这也算另类的签名。纪念吧。
(2)性能优化修改
【build.prop优化项目】
修改方法:第一步:进入build.pro ,光标移动到末尾。 第二步:按回车键,另起一行输入相应的这些参数。(注意大小写和符号!!你们自己的失误如果出现状况我不负责。)第三步:保存,退出然后重启手机即可。。)
1. 强制把Home程序驻入内存. ro.HOME_APP_ADJ=1
2.提高 JPG 质量为 100%ro.media.enc.jpeg.quality=100
3. VM 虚拟堆大小; 提高 RAM(这个里面已经有了,你要做的是把后面的数字修改为48或者64都可以,提高游戏性能。) dalvik.vm.heapsize=48m(也可以修改为64,官方ROM默认32)
4. 使用 GPU 渲染UI debug.sf.hw=1
5. 减少拨号后出现的延时ro.telephony.call_ring.delay=0
6.提高滑动响应 windowsmgr.max_events_per_sec=150
7.电池优化 wifi.supplicant_scan_interval=180 pm.sleep_mode=1 ro.ril.disable.power.collapse=0
8. 禁止调试通知图标出现在状态栏处 persist.adb.notify=0
9. 提高全局触摸屏响应 debug.performance.tuning=1 video.accelerate.hw=1
10. 提高图片和摄像质量 ro.media.dec.jpeg.memcap=8000000 ro.media.enc.hprof.vid.bps=8000000
11. (3G) 信号优化 ro.ril.hsxpa=2 ro.ril.gprsclass=10 ro.ril.hep=1 ro.ril.enable.dtm=1 ro.ril.hsdpa.category=10 ro.ril.enable.a53=1 ro.ril.enable.3g.prefix=1 ro.ril.htcmaskw1.bitmask= ro.ril.htcmaskw1=14449 ro.ril.hsupa.category=5
12. 网络速度优化 net.tcp.buffersize.default=,6, net.tcp.buffersize.wifi=,6, net.tcp.buffersize.umts=,6, net.tcp.buffersize.gprs=,6, net.tcp.buffersize.edge=,6,
13. 禁止拨号后出现黑屏. ro.lge.proximity.delay=25 mot.proximity.delay=25
14.修复应用程序出现问题. ro.kernel.android.checkjni=0
15.不通过按加/减音键唤醒手机 ro.config.hwfeature_wakeupkey=0
16.屏幕点亮时强制开启功能键背光ro.mot.buttonlight.timeout=0
17.不显示开机动画(system/media/bootanimation.zip动画将不显示,加速开机速度)& & debug.sf.nobootanimation=1
18.其他优化 ro.config.hw_menu_unlockscreen=false persist.sys.use_dithering=0 persist.sys.purgeable_assets=1 dalvik.vm.dexopt-flags=m=y ro.mot.eri.losalert.delay=1000
【提示】:
你们可以将这些小代码复制进入一个新建的TXT文档,然后放入SD卡根目录然后复制粘贴里面的代码到Build.pro里。这么说你们懂了吧?喜欢手动输入的注意大小写!和符号喔。。我这里上传提供62版本和58版本的我已经弄好的build.pro你们按美化方法,复制进入system/app 目录里改211权限后移动到system目录下替换即可。(因为build.pro就在system目录下,你如果复制到这。你懂的。。没改权限就替换的话就等着刷机吧。。。。
1 d. U9 K0 r( H. }& Z
(83 Bytes, 下载次数: 29)
日 15:29 上传
点击文件名下载附件
下载积分: 松鼠币 -2
上UC,有快感!
该帖共收到 15 条回复!
发表于 日 15:33
不错不错,不知通用没
上UC,有快感!
发表于 日 15:40
虽不懂但觉厉
上UC,有快感!
发表于 日 15:58
有一键优化build
上UC,有快感!
发表于 日 16:27
支持技术教程。
上UC,有快感!
发表于 日 16:32
上UC,有快感!
发表于 日 17:16
切,就这……做rom精简优化的都顺没效果的,还有个索爱Bravia Eng:
Bravia Engine技术针对tft屏进行修复,可以增加其亮度而不增加功耗,同时减小图片及影像的像素噪点,色彩还原更准确,画面更精细有点类似ip4的视网膜技术,这个技术最终的衍生体就slcd屏,所以大家明白了吧ine技术修改教程,
上UC,有快感!
发表于 日 17:35
先顶,在收藏~~
上UC,有快感!
发表于 日 19:38
其实这个也是双刃剑,性能上去了,电量下来了
上UC,有快感!
发表于 日 20:59
这么神奇。
上UC,有快感!
发表于 日 21:02
楼主的一些value并不全所有机型都有的。。。
mot一词很明显。。
上UC,有快感!
发表于 日 12:15
节日快乐了,谢谢分享了
上UC,有快感!
发表于 日 02:13
提示: 作者被禁止或删除 内容自动屏蔽
上UC,有快感!
发表于 日 21:02
上UC,有快感!
发表于 日 01:37
提示: 作者被禁止或删除 内容自动屏蔽
上UC,有快感!Android持续优化 - 提高流畅度 - CSDN博客
Android持续优化 - 提高流畅度
/purediy/p/3492865.html
/purediy/p/3492865.html
/purediy/p/3492865.html
一.形象的感官一下流畅度概念
1. 这是官方给出的概念:Android流畅运行,需要运行60帧/秒, 则需要每帧的处理时间不超过16ms。
2. 每秒帧数,实际上就是指动画或视频每秒放映的画面数。因此“帧”的概念就是指“画面”,1幅画就叫做“1帧”,每秒帧数指的就是“每秒播放的画面数”。帧数就是在1秒钟时间里传输的图片的量,也可以理解为图形处理器每秒钟能够刷新几次,通常用fps(Frames Per Second)表示。每一帧都是静止的图象,快速连续地显示帧便形成了运动的假象。高的帧率可以得到更流畅、更逼真的动画。每秒钟帧数
(fps) 愈多,所显示的动作就会愈流畅。
3. 一帧占用内存数
当画面的分辨率是,刷新率要达到60帧/秒时,那么显卡在一秒钟内需要处理的像素量就达到了“×60=5713920”。那么一个“像素量”,相当与占用多少内存?我们用位图来代替粗略计算,把分辨率是看成一张对应大小的位图,通过位图的大小来大概计算占用的内存大小。而位图的存储算法,在维基百科上有详细的介绍,详见下面的链接。
一张的16位(bit)位图文件大小 = ×16/8 = 1572864 B = 1536 KB = 1.5 MB。如果要求画面的刷新率达到60帧/秒,则每秒需要处理的数据量就达到1.5 * 60 = 90 MB,这个数据是相当大。
实际系统中会通过GPU显卡处理显示,减少CPU工作量,或者系统会缓存或局部刷新来降低处理量。没有研究过,也很想研究一下显示的流程。
二.Android流畅度的根本:解放UI主线程
1. 不要阻塞UI线程;
2. 不要在UI线程之外操作UI。
三.以ListView加载图片为例
1. ListView如何流畅顺滑加载?
2. ListView使用convertView可以提高两倍性能?
3. ListView回收item的原理是什么?
4. ListView重复加载调用的问题?
5. 如何解决图片加载OOM问题?
6. 如何更流畅的加载图片?
7. ListView加载大量图片并发问题?
ListView优化要点
1.&,使用convertView,效率提高2倍;
2.&,提高整体性能;
3.&可以设置layout_height高度固定或者fill_parent,加载的原理;
4. 使用addHeader和addFooter代替ScrollView;
图片加载优化要点
1. 有效加载大图片,合理设置BitmapFactory.Options的值,减少图片内存占用;
2. 仅请求图片的大小,inJustDecodeBounds&=
true,仅请求图片大小,而不会加载图片到内存;
3. 缓存图片,内存缓存,硬盘缓存&DiskLruCache;
4. 使用非UI线程加载图片,使用&;
5. 使用软引用,绑定ImageView和url,处理ListView并发加载问
Google官方教程(一定要读):
其他好文章:
/purediy/p/3232996.html
/purediy/p/3232996.html
/purediy/p/3232996.html
优化布局层次结构
一个普遍的误解就是,使用基本的布局结构会产生高效的布局性能。然而每一个添加到应用的控件和布局,都需要初始化,布局位置和绘制。比如,使用一个嵌套的LinearLayout会导致过深的布局层次结构。此外,嵌套多个使用layout_weight属性的LinearLayout实例会花费更大的代价,因为每一个子布局都要测量两次。当某个布局被频繁渲染时,比如它在ListView或GridView中使用,就显得尤为重要。
在这节课中,将学会使用Hierachy Viewer和Layoutopt工具对布局结构进行检测和优化。
检测你的布局
在Android SDK tools中包含一个叫做HierchyViewer工具,它可以在你运行应用时候帮助你分析你的布局性能。通过它你可以发现你的布局中性能比较差的那些地方。
HierchyViewer需要你选择一个已链接的设备或者模拟器中的一个运行的线程,显示出布局的树结构。每个块上的红绿灯代表它的测量,布局,以及绘图性能,帮助你找出潜在的问题。
比如,图1显示了一个用于ListView中的Item的布局。这个布局的左边显示了一幅图片,两个叠在一起的文字item放在右边。那些被重复加载的布局在优化时候显得有为重要。
图1. 一个ListView内item的概念设计
hierchyviewer 工具可以在&sdk&/tools/中找到。当打开给工具后,就会显示可用的设备列表一个这些设备中运行的部分。点击“Load View Hierchy”选项查看被选中部分的布局层次图。比如,图2显示了图1中布局结构图。
图2. 图1的布局层次结构图,使用内嵌的LinearLayout实例布局。
图3. 点击层次图中一个节点,显示它的运行时间
图2中,你可以看到一个3层的布局结构图,并且在布局text的items里面有一些问题。点击这些items显示进程中每个阶段所花费的时间。它显示的很清楚,哪些items在测试,布局中花费时间最长,哪些地方需要花费时间去优化。
使用该布局加载所有item所花费的时间如下:
Measure: 0.977ms
Layout: 0.167ms
Draw: 2.717ms
因为上述布局性能较低的原因主要是由一个内嵌的LinearLayout所引起,将该布局使用浅而广的扁平化结构代替深而窄的树形结构化设计,从而提高性能。在这些布局中,将RelativeLayout作为一个根节点,这样,你将会看到该布局变为一个2层的结构,修改后的布局如下:
图4. 使用RelativeLayout的图1的布局。
修改后加载item所花费的时间:
Measure: 0.598ms
Layout: 0.110ms
Draw: 2.146ms
虽然看起来提高度很小,但是这布局提高是被重复操作的,因此,这个布局是在listview中的每一个item里面。
更多情况的一个时间差异,是在使用了layout_weight属性的LinearLayout设计里面,这样的设计会降低测量的速度。这只是一个示例说明每个布局是否被适当的使用,在使用layout weight属性时候,你应该谨慎考虑是否必要。
这是一个好习惯,在你的布局文件内运行Lint工具,寻找那些可能要优化的布局结构。Lint工具代替Layoutopt工具,并且有更大的功能。如下是Lint的一些示例:
使用复杂的图片:在LineraLayout布局中包含一个ImageView和一个TextView,可以使用一个复杂的drawable代替,性能会更好。合并根框架:假如一个FrameLayout作为一个布局的根视图,不提供背景或者填充,它可以被一个带有&merge/&标志的布局代替。无用的树叶:对于一个扁平结构中一个布局没有孩子,没有背景,可以被删掉。无用的父类:一个布局不是ScrollView或者不是一个根布局,也没有背景,只有一个孩子节点,可以被删掉,孩子节点直接放入到这个扁平的父类里面。深度布局:布局若有太多内嵌,则性能很差。考虑使用RelativeLayout 以及GridLayout等扁平化布局代替。默认布局最大深度是10.
使用Lint另一个好处是,它被内嵌到ADT16+.当你在导入apk,编辑或者保存一个xml文件,Lint都会自动运行。点击Eclipse工具栏中Lint按钮,会人为强制运行Lint.
在Eclipse内使用Lint,它能自动修复一些问题,为问题提供修改建议,直接掉转到问题代码位置。如果你不是用Eclipse开发,也可以使用命令行启动Lint。更多信息请参照.
/article/8065f87fcc82.html
/article/8065f87fcc82.html
/article/8065f87fcc82.html
一直以来&&给人的感觉都是各种卡顿,尤其是开的程序比较多以后,和&&比较起来流畅度上会有不小的差距,实际上我们只要优化得当,Android也能很流畅,丝毫不逊色于
iPhone……
本文主要介绍的是从优化、第三方软件优化以及设置优化几方面结合来。
系统这一块绝对是有着举足轻重的地位,一款好的系统能让 Android 脱胎换骨。而从Android &4.1开始,Android 的流畅性可以说有了质的飞跃。Android 4.1的触控感觉非常好,这主要归功于 Android &4.1的帧速度提高到了60fps,而且在触摸延迟上有更加优秀的表现。因此只要情况允许,建议所有 Android 手机都刷到4.1以上,这种体验绝对是以往使用4.0甚至2.3系统都不可想象的。当然,对于大部分 Android 手机来说,4.1还是遥不可及,只有通过第三方 ROM 才能达到品尝“果冻豆”的目的,这里就要特别注意第三方
ROM 的稳定性问题。
如果不能刷 Android 4.1,那还可以选择一些第三方 ROM 例如原生系统 AOKP 或者 CM 系列。由于系统非常精简,这些第三方 ROM 也会带来流畅度的提升,当然要放弃的是官方 ROM 的各种自带软件和 UI,这就要看用户的取舍了。
Android 手机的内核(Kernel)对手机流畅性也是有很大的影响,内核直接影响 CPU 的运行效率、频率变化。说到刷内核就不能不提超频,一些第三方内核支持 CPU 的超频,CPU 频率提高了流畅度当然会有变化,当然这里也要特别注意温度和电压的控制。
2.设置优化
开启性能模式
这个问题在此前的文章“如何让你的手机更省电?”中已经有提及过,很多手机默认是标准模式甚至是省电模式,这对性能是有不少影响的,因此建议不是有特别需求还是调至性能模式(位置:系统设置,因不同手机而异)。
关闭动画特效
这是一个 Android 4.0才开始有的设置选项,Android 4.0有两项(窗口动画缩放以及过渡动画缩放),Android 4.1增加了程序时长调整。有人说 Android 的动画比较卡,没有iPhone顺滑,有这选项可好,你说动画不顺嘛,我关掉还不行吗?关闭了这些以后会感觉反应迅速了很多,但是牺牲了一定的视觉感受(位置:设置→开发人员选项)。
不保留活动
这个选项即把 Android 相对 iPhone 的其中一个很大的优势舍弃了,也就是我们常说的“多任务”,Android 现在的高端机动不动就四核、2G RAM,如果只跑一个软件,可想而知流畅度会非常高,但是这里并不建议使用这种方法提升流畅度,没有多任务的 Android 更像一只三脚猫,如果只是体验一下那种感觉也无妨(位置:设置——开发人员选项)。
本文已收录于以下专栏:
相关文章推荐
Android之GPU过度绘制与图形渲染优化写在前面的话本文主要对过度绘制和图形渲染做一个概念性的描述,和简单的优化措施。
如果你已对过度绘制有过一些了解,那么你应该明白,仅是简单的层级优化对过度绘...
Android内核开发:系统启动速度优化
标签:启动 优化 速度 boot Android
原创作品,允许转载,转载时请务必以超链接形式标...
在app发展中期,大多数功能都已经健全,优化性能问题成为了主要的工作任务。很多时候页面卡顿或者app占用内存过高是由于一些耗时操作,比如数据库操作引起的。但是也有些情况不是耗时操作引起的,比如whil...
发现更新Android Studio 后运行程序的时候 360检测球显示CPU百分之九十以上,内存严重不足。直接卡了三分钟左右,程序才运行成功,后来发现并不是更新问题,新建一个HelloWorld代码...
在学习新知识的过程中,我一直很推荐结合实战任务去学习,只有经历实战,才能加深对理论知识的理解。《Android内核开发》系列已经写了八篇了,本文就结合前面的内容,给大家布置一个实战任务: 优化Andr...
当我们在写Android代码的时候有时候UI界面上的控件太多代码就特别冗余,findViewById() setOnClickListener()... 郁闷
看看我一般是怎么做的吧~
本文由 伯乐在线 - 至秦 翻译,唐尤华 校稿。未经许可,禁止转载!
英文出处:Udi Cohen。欢迎加入翻译组。
我在几周前的 Droidcon NYC 会议上,做了一个关于 Androi...
在开发过程中,我们会遇到手机的CPU使用率过高而引发的问题,那接下来,我对这方面知识做些整理及归纳
1. CPU使用背景知识:
CPU利用率是指:CPU执行非系统空闲进程的时间 / CPU总的执行...
转载自:http://blog.csdn.net/lmj/article/details/
2015年初google发布了Android性能优化典范...
[原] Android持续优化 - 提高流畅度
一.形象的感官一下流畅度概念
1. 这是官方给出的概念:Android流畅运行,需要运行60帧/秒, 则需要每帧的处理时间不...
他的最新文章
讲师:吴岸城
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)网站配置未生效 |
| 百度云加速
请打开cookies.
你访问的网站() 使用了
网络。 百度云加速目前无法解析此域名 ().
主要因为: 网站主刚刚在百度云加速添加了这个域名,百度云加速需要几十秒的时间同步到全球网络中。稍等片刻刷新页面即可解决。
也有可能: 网站配置出错.程序猿如何从产品的角度去提升应用的体验之Android权限优化篇
前言:大家平时在开发的过程中是否会遇到这种情况:很多产品体验上的细节,特别是涉及到技术相关的细节,产品与设计可能并不会给出详细的解决方案,甚至可能并不太关注这方面的体验细节。例如,应用的缓存清理机制该怎么实现?权限申请的时机应该放在哪?用户没有给予应用必要的权限该怎么处理......这种时候,作为一个开发人员,特别是对自家产品的使用体验有追求的开发人员,其实完全可以充当一回产品,从产品的角度出发去思考,该怎样在技术实现的细节上,让自家的APP体验变得更好。千万不要小瞧这些细节,一个产品的极致体验,就是由无数的细节堆砌而成的。
1. 应用通知权限的优化
众所周知,推送对于一个APP来说是很重要的功能。推送在好的产品设计中可以有效地提高产品活跃度,增加用户的忠诚度以及留存率。但是,用户有可能会在无意中把应用的通知权限给禁止了,导致收不到推送(用户主动禁止应用的通知权限除外)。例如,华为手机会在通知中心直接提示用户是否关掉某个应用的通知权限。如果用户,特别是小白用户一不小心把通知权限给禁止了,导致应用收不到推送,反而可能还会把这种情况当做bug来向客服反馈(任何时候都千万不要高估用户对于智能手机使用的了解,尤其是你的APP的目标用户还包括中老年人的时候)。
华为手机的推送中心
如果大家有细心观察的话会发现,当应用的通知权限被禁止的时候,体验好的应用会在适当的时机以及场景下出现提示,告知用户通知在应用中起到的作用,尝试去消除用户的不信任和谨慎心理,并引导用户去打开通知权限。
那么,我们怎么知道自己的应用程序通知权限被禁止了呢?如果被禁止了又该怎么办呢?下面就来说一下解决方案。
1.1 检测应用的通知权限状态
检测应用的通知权限其实比较简单。通过查询 官方文档 可以发现,在support库的API 24.0.0 版本,已经有现成的方法可以直接查询应用的通知权限状态:
NotificationManagerCompat.from(this).areNotificationEnable();
但是,这就意味着应用的 compileSdkVersion 也需要与support库的版本保持一致。如果应用目前所使用的compileSdkVersion 低于 24.0.0 或者由于某些历史原因而不能将compileSdkVersion 升到 24.0.0以上,那么就没有办法检测到应用的通知权限了吗?
其实,办法还是有的。通过查看系统源码,可以发现,NotificationManagerCompat.from(this).areNotificationEnable() 这个方法在不同版本的SDK上会有不同的实现。
/** * Returns whether notifications from the calling package are not blocked. */public boolean areNotificationsEnabled() { returnIMPL.areNotificationsEnabled(mContext, mNotificationManager);}
IMPL是一个实现了Impl接口的实现类对象,而且在静态代码块中通过判断手机系统所使用的版本号来初始化不同的实现类:
static { if(BuildCompat.isAtLeastN()) { IMPL = new ImplApi24(); } elseif(Build.VERSION.SDK_INT &= 19) { IMPL = new ImplKitKat(); } elseif(Build.VERSION.SDK_INT &= 14) { IMPL = new ImplIceCreamSandwich(); } else{ IMPL = new ImplBase(); } SIDE_CHANNEL_BIND_FLAGS = IMPL.getSideChannelBindFlags();}
当手机系统Android版本小于4.4.0的时候, areNotificationEnable()方法会默认返回true。所以,此方法只有在4.4.0以上的手机系统上才能返回准确的结果。
ImplApi24类中areNotificationEnable()的实现如下:
/** * Returns whether notifications from the calling package are blocked. */public boolean areNotificationsEnabled() { INotificationManager service = getService(); try { returnservice.areNotificationsEnabled(mContext.getPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); }}
ImplKitKat类中areNotificationEnable()的实现如下:
public static boolean areNotificationsEnabled(Context context) { AppOpsManager appOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE); ApplicationInfo appInfo = context.getApplicationInfo(); String pkg = context.getApplicationContext().getPackageName(); int uid = appInfo. try { Class&?& appOpsClass = Class.forName(AppOpsManager.class.getName()); Method checkOpNoThrowMethod = appOpsClass.getMethod(CHECK_OP_NO_THROW, Integer.TYPE, Integer.TYPE, String.class); Field opPostNotificationValue = appOpsClass.getDeclaredField(OP_POST_NOTIFICATION); int value = (int) opPostNotificationValue.get(Integer.class); return((int) checkOpNoThrowMethod.invoke(appOps, value, uid, pkg) == AppOpsManager.MODE_ALLOWED); } catch (ClassNotFoundException | NoSuchMethodException | NoSuchFieldException | InvocationTargetException | IllegalAccessException | RuntimeException e) { returntrue; }}
这种反射的方式实际上就是通过AppOpsManager和AppOpsService去获取位于/data/system/目录下的文件Appops.xml里的数据。所以,这个系统源码里的方法可以单独抽取出来作为一个通用的检测通知权限状态的方法。有关AppOpsManager,这里先不做展开,等下在1.4章节单独说一下。
1.2 引导用户跳转到通知权限设置界面
既然已经能检测到应用的通知权限状态,当应用的通知权限被禁止的时候,应该出现提示告知用户通知在应用中起到的作用,并引导用户去打开通知权限。以下为跳转到通知权限设置的通用方法:
public void toNotificationSetting() { if(android.os.Build.VERSION.SDK_INT &= Build.VERSION_CODES.LOLLIPOP) { Intent intent = new Intent(); intent.setAction( "android.settings.APP_NOTIFICATION_SETTINGS"); intent.putExtra( "app_package", this.getPackageName()); intent.putExtra( "app_uid", this.getApplicationInfo().uid); startActivity(intent); } elseif(android.os.Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT) { Intent intent = new Intent(); intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); intent.addCategory(Intent.CATEGORY_DEFAULT); intent.setData(Uri.parse( "package:"+ this.getPackageName())); startActivity(intent); }}
在5.0以上,可以直接跳转到某个应用的通知权限快捷设置界面。但是在5.0以下,暂时还没有找到可以直接跳转到通知权限设置界面的方法,所以目前的做法是跳转某个应用的设置界面,在设置界面列表中应该会有通知权限管理的入口。如果你有更好的做法,欢迎在评论中指出来。这里再另外抛出一个问题,供大家思考:关于通知权限提示的方案,应该在什么时机或场景下出现好?出现提示的频率为多少好呢?是只提示一次呢,还是只要用户没打开通知权限就一直提示呢?欢迎大家在留言中说出自己的看法。
1.3 当通知权限被关闭后,Toast可能无法正常工作的问题
虽然跟通知权限的优化没什么关系,不过在这里还是要提一下。这个是在调研通知权限优化问题的时候偶然发现的坑:在大部分的机型上,当应用的通知权限被关闭后,系统的 Toast会直接无法正常工作。
以下是我测试过的数据:
可以看出,这个坑影响的机型范围还是挺大的。为什么会这样呢?
查阅源码后可以发现 Toast 里也用到了NotificationManagerService。在Toast执行show()方法后,执行到enqueueToast()的时候如下:
if(ENABLE_BLOCKED_TOASTS && !noteNotificationOp(pkg, Binder.getCallingUid())) { if(!isSystemToast) { Slog.e(TAG, "Suppressing toast from package "+ pkg + " by user request."); return; }}
原来这里也用到了检测通知权限的方法noteNotificationOp()。如果通知权限被禁止了,那么Toast也就无法正常工作。
对于Android手机来说,Toast在应用中随处可见,如果因为通知权限导致Toast不工作那么影响还是挺大的。所以,在这里建议大家寻找一下Toast的替代方案,不要在项目中直接使用系统自带的Toast。同样的,如果大家有什么好的解决方案,也欢迎在留言中指出来。
1.4 AppOpsManager的工作原理
既然上面提到了AppOpsManager,那么这里来简单地介绍一下它的工作原理。AppOpsManager的工作框架图如下:
Setting UI通过AppOpsManager与AppOpsService 交互,给用户提供入口管理各个app的操作。
AppOpsService具体处理用户的各项设置,用户的设置项存储在 /data/system/appops.xml文件中。
AppOpsService也会被注入到各个相关的系统服务中,进行权限操作的检验。
各个权限操作对应的系统服务(比如定位相关的Location Service,Audio相关的Audio Service等)中注入AppOpsService的判断。如果用户做了相应的设置,那么这些系统服务就要做出相应的处理。比如,LocationManagerSerivce的定位相关接口在实现时,会有判断调用该接口的app是否被用户设置成禁止该操作,如果有该设置,就不会继续进行定位。
2. 应用权限的提示优化
由于篇幅的原因,这里就拿相机权限来举例。假设需求如下:
在需要使用相机的场景下,先提前检测相机权限是否打开,如果没有打开,则尝试申请相机权限,如果用户还是拒绝,则出现权限提示,引导用户去开启相机权限。下面是微信的处理方式:
(1)6.0系统以上,先尝试申请相机权限,用户点击禁止后弹出引导界面
(2)6.0系统以下,用户点击保持禁止后弹出引导界面
在6.0以上,我们一般可以通过系统自带的方法来检测某个权限是否被允许:
ActivityCompat.checkSelfPermission(context, permission)
但是,在6.0以下,如果想检测相机权限,却没有一个很好的方法。最后,经过查阅各种资料,发现好像只能通过一种简单粗暴的方式去检测相机权限:
/** * 在6.0系统以下,通过尝试打开相机的方式判断有无拍照权限 * * @ return*/private boolean checkCameraPermissionUnderM() { boolean isCanUse = true; Camera mCamera = try { mCamera = Camera.open(); Camera.Parameters mParameters = mCamera.getParameters(); mCamera.setParameters(mParameters); } catch (Exception e) { isCanUse = false; } if(mCamera != null) { try { mCamera.release(); } catch (Exception e) { e.printStackTrace(); returnisCanU } } returnisCanU}
当使用这个方法的时候,在6.0以下的手机,一般调用 Camera.open()方法,如果相机权限没打开,会先弹出相机权限申请弹框。如果点击允许,那么该方法就会返回true,点击禁止则返回false。这里需要指出的是,如果你使用相机的方式是通过Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE)来跳转到系统的相机界面的话,那么即使应用的相机权限被禁止了,也还是可以正常使用相机来拍照的。这种情况下要不要做权限检查,就看个人的看法了。
不知道大家有没注意到,微信在6.0以上和6.0以下弹出的提示对话框有点不同。在6.0以上提供“去设置”的选项,点击会跳转到设置里的应用列表界面,在6.0以下仅仅是提示。这也是一个产品的细节。个人看法,因为在6.0以下,有些国产系统的权限管理根本就不在设置里面,而是需要到官方提供的手机管家类型应用里面才可以进行权限的管理。那么多的国产系统,需要适配有点困难,如果没有很好的解决方案,那么还不如不要擅自帮用户做决定。可以看得出微信在跳转到权限设置界面的适配上也经过了一番考量,最后选择了这种折中的方案。
说到这里,既然权限提示优化的思路已经有了,大家也可以在自己的项目中封装一个权限管理类,“检查权限-被禁止-尝试申请权限-被拒绝-弹出提示框-引导用户去打开权限”通过一个方法一气呵成。
本文涉及到的知识点可能并不深奥,更多的是想向大家展示一下,假如开发人员从产品的角度去提升应用的体验,可以从什么角度去切入。如果能给大家带来一些启发就好了。看完文章后,不凡思考一下,自己的应用在权限提示上的体验是否做到最好了呢?如果还有可以改善的地方,那么赶紧根据自家应用的实际情况,改善一下权限提示的体验吧。相信我,做了这件事,你的用户会感激你的。
责任编辑:
声明:本文由入驻搜狐号的作者撰写,除搜狐官方账号外,观点仅代表作者本人,不代表搜狐立场。
今日搜狐热点

我要回帖

更多关于 一招让安卓跟苹果流畅 的文章

 

随机推荐