扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
GUI,界面,与用户交互的可视接口。
站在用户的角度思考问题,与客户深入沟通,找到涿州网站设计与涿州网站推广的解决方案,凭借多年的经验,让设计与互联网技术结合,创造个性化、用户体验好的作品,建站类型包括:成都做网站、网站建设、企业官网、英文网站、手机端网站、网站推广、主机域名、网页空间、企业邮箱。业务覆盖涿州地区。
当然Fragment,View也是,不过我把它看作是控件,Activity是开发中最基本的容器(窗口)。
目的是便于管理Activity生命周期。
新启动的Activity会压入栈顶,而处于栈顶的Activty处于Active活跃状态,即可以和用户做交互(可见可交互)。压在下面的Activity则处于可见不可交互,或不可见不可交互状态,并且系统可能会因为内存不足原因优先回收掉任务栈最下面的Activity,所以也有被回收状态。
1.资源相关的系统配置发生改变导致Activty被杀死并重新创建
2.资源内存不足导致低优先级的Activity被杀死
扩展:进程优先级
当Activity异常被回收的情况下,系统会调用onSaveIntanceState(Bundle),重新启动时会调用onRestoreInstanceState(Bundle),所以可以在Bundle做一些数据保存和恢复的工作。
数据恢复:onCreate()与onRestoreInstanceState()区别:
onCreate()需要判空,onRestoreInstanceState不需要。
启动模式简单来说就是定义Activity实例与Activity任务栈的关联方式。
目的:
设置方式:
有哪些启动模式?
TaskAffinity(任务相关性),这个参数标识了一个Activity所需要的任务栈的名字,默认情况下,所有Activity所需的任务栈的名字为应用的名字。所有我们可以通过设置TaskAffinity为每个Activity单独指定任务栈。
启动Activity就两种,显示调用和隐式调用。
即在Intent中,显示传入要跳转的组件类名。这种方式比较简单直接,但也造成了关联耦合。
这样调用方式的好处是我不必知道我的目标组件具体的名字,只要有组件满足我设置的过滤条件即可找到我想要的组件。这种方式广泛应用在模块化开发,解决了模块之间的跳转问题。
隐式调用需要Intent能够匹配目标组件的IntentFilter中设置的过滤信息,如果不匹配将无法启动目标组件。IntentFilter中的过滤信息包括action、category、data
清单文件中,如果data仅指定了mimeType,没有指定URI,则data中URI的scheme的默认值为file和content,所以Intent中URI的scheme也必须为file或content才能匹配到。
类似URI的结构,就是匹配URI的。
URI结果: scheme://host:port/[path|pathPrefix|pathPattern]
使用PackageManager的两种方法判空。
第二个flag参数使用MATCH_DEFAULT_ONLY时,表示仅仅匹配那些在intent-filter中声明了android.intent.category.DEFAULT这个category的组件。
常用的Android性能优化方法:
一、布局优化:
1)尽量减少布局文件的层级。
层级少了,绘制的工作量也就少了,性能自然提高。
2)布局重用 include标签
3)按需加载:使用ViewStub,它继承自View,一种轻量级控件,本身不参与任何的布局和绘制过程。他的layout参数里添加一个替换的布局文件,当它通过setVisibility或者inflate方法加载后,它就会被内部布局替换掉。
二、绘制优化:
基于onDraw会被调用多次,该方法内要避免两类操作:
1)创建新的局部对象,导致大量垃圾对象的产生,从而导致频繁的gc,降低程序的执行效率。
2)不要做耗时操作,抢CPU时间片,造成绘制很卡不流畅。
三、内存泄漏优化:
1)静态变量导致内存泄漏 比较明显
2)单例模式导致的内存泄漏 单例无法被垃圾回收,它持有的任何对象的引用都会导致该对象不会被gc。
3)属性动画导致内存泄漏 无限循环动画,在activity中播放,但是onDestroy时没有停止的话,动画会一直播放下去,view被动画持有,activity又被view持有,导致activity无法被回收。
四、响应速度优化:
1)避免在主线程做耗时操作 包括四大组件,因为四大组件都是运行在主线程的。
2)把一些创建大量对象等的初始化工作放在页面回到前台之后,而不应该放到创建的时候。
五、ListView的优化:
1)使用convertView,走listView子View回收的一套:RecycleBin 机制
主要是维护了两个数组,一个是mActiveViews,当前可见的view,一个是mScrapViews,当前不可见的view。当触摸ListView并向上滑动时,ListView上部的一些OnScreen的View位置上移,并移除了ListView的屏幕范围,此时这些OnScreen的View就变得不可见了,不可见的View叫做OffScreen的View,即这些View已经不在屏幕可见范围内了,也可以叫做ScrapView,Scrap表示废弃的意思,ScrapView的意思是这些OffScreen的View不再处于可以交互的Active状态了。ListView会把那些ScrapView(即OffScreen的View)删除,这样就不用绘制这些本来就不可见的View了,同时,ListView会把这些删除的ScrapView放入到RecycleBin中存起来,就像把暂时无用的资源放到回收站一样。
当ListView的底部需要显示新的View的时候,会从RecycleBin中取出一个ScrapView,将其作为convertView参数传递给Adapter的getView方法,从而达到View复用的目的,这样就不必在Adapter的getView方法中执行LayoutInflater.inflate()方法了。
RecycleBin中有两个重要的View数组,分别是mActiveViews和mScrapViews。这两个数组中所存储的View都是用来复用的,只不过mActiveViews中存储的是OnScreen的View,这些View很有可能被直接复用;而mScrapViews中存储的是OffScreen的View,这些View主要是用来间接复用的。
2)使用ViewHolder避免重复地findViewById
3)快速滑动不适合做大量异步任务,结合滑动监听,等滑动结束之后加载当前显示在屏幕范围的内容。
4)getView中避免做耗时操作,主要针对图片:ImageLoader来处理(原理:三级缓存)
5)对于一个列表,如果刷新数据只是某一个item的数据,可以使用局部刷新,在列表数据量比较大的情况下,节省不少性能开销。
六、Bitmap优化:
1)减少内存开支:图片过大,超过控件需要的大小的情况下,不要直接加载原图,而是对图片进行尺寸压缩,方式是BitmapFactroy.Options 采样,inSampleSize 转成需要的尺寸的图片。
2)减少流量开销:对图片进行质量压缩,再上传服务器。图片有三种存在形式:硬盘上时是file,网络传输时是stream,内存中是stream或bitmap,所谓的质量压缩,它其实只能实现对file的影响,你可以把一个file转成bitmap再转成file,或者直接将一个bitmap转成file时,这个最终的file是被压缩过的,但是中间的bitmap并没有被压缩。bitmap.compress(Bitmap.CompressFormat.PNG,100,bos);
七、线程优化:
使用线程池。为什么要用线程池?
1、从“为每个任务分配一个线程”转换到“在线程池中执行任务”
2、通过重用现有的线程而不是创建新线程,可以处理多个请求在创建销毁过程中产生的巨大开销
3、当使用线程池时,在请求到来时间 ,不用等待系统重新创建新的线程,而是直接复用线程池中的线程,这样可以提高响应性。
4、通过和适当调整线程池的大小 ,可以创建足够多的线程以使处理器能够保持忙碌状态,同时还可以防止过多线程相互竞争资源而使应用程序耗尽内存或者失败。
5、一个App里面所有的任务都放在线程池中执行后,可以统一管理 ,当应用退出时,可以把程序中所有的线程统一关闭,避免了内存和CPU的消耗。
6、如果这个任务是一个循环调度任务,你则必须在这个界面onDetach方法把这个任务给cancel掉,如果是一个普通任务则可cancel,可不cancel,但是最好cancel
7、整个APP的总开关会在应用退出的时间把整个线程池全部关闭。
八、一些性能优化建议:
1)避免创建过多对象,造成频繁的gc
2)不要过多使用枚举,枚举占用的空间比整型大很多
3)字符串的拼接使用StringBuffer、StringBuilder来替代直接使用String,因为使用String会创建多个String对象,参考第一条。
4)适当使用软引用,(弱引用就不太推荐了)
5)使用内存缓存和磁盘缓存。
1.调用系统的分享功能
2.通过第三方SDK,如ShareSDK,友盟等
3.自行使用各自平台的SDK,比如QQ,微信,微博各自的SDK
本文只是关于如何实现Android系统分享,并非第三方SDK实现方法
Android开发时通过startActivity发送action为Intent.ACTION_SEND的Intent即很容易就可以实现系统分享功能,举个简单例子看看:
从例子中,可以发现实现系统分享主要由三部分Action、Extras和Type组成。首先将Intent的cation设置为Intent.ACTION_SEND,其次根据分享的内容设置不同的Type,然后根据不同的社交平台设置相关Extras,最后将Intent发送出去即可完成系统分享。
1.如何将自己的应用能够显示在系统分享的应用选择框中?
根据以上介绍,我们可以在应用清单文件中使用intent-filter来完成;
2.如何监听在应用选择框中,选择了那个应用?
需要采用BroadcastReceiver来实现:(该方法在部分手机上可以实现,并且需要API Level大于等于22)
3.如何为制定应用设置分享type?
4.如何只显示指定的应用?
Xfermode表示图层的混合模式,用于描述两个图层之间进行融合时,像素点进行计算的规则。
在API16之前,Xfermode有3个子类:AvoidXfermode、PixelXorXfermode、PorterDuffXfermode。但在API16以后,前两个已经过时,甚至从源码里移除,所以我们只需学习 PorterDuffXfermode 即可。
PorterDuffXfermode 最早是在1984年由Porter和Duff两人发表的论文《Compositing Digital Images》中出现,所以该混合模式也根据作者来命名。
PorterDuffXfermode 构造函数需要指定一个 PorterDuff.Mode ,而PorterDuff.Mode在以下地方都会涉及:
它提供18种模式可选项:
各种模式下的效果如下图所示:
这里可以发现,两种效果是不一样的,谷歌官方给的是第一种,但是,通常情况应该是第二种,具体原因可 参考该文章 。比如我们画一个矩形,应该按第二种效果来考虑,因为源图和目标图大小不一致;如果画相同大小的Bitmap,则按第一种做。
在实际应用中,我们可以从以下三个方面来决定使用哪种模式:
1、没有硬件加速:
invalidate the view hierarchy ------ draw the view hierarchy
2、有硬件加速:
invalidate the view hierarchy ------ record and update the display list ------ draw the display list
1、绘制不正确:可能使用了不支持硬件加速的操作, 需要关闭硬件加速或者绕过该操作
2、抛出异常:可能使用了不支持硬件加速的操作, 需要关闭硬件加速或者绕过该操作
在Android系统中,有4个不同级别的打开或者关闭硬件加速操作:
1、Application级别:
application android:hardwareAccelerated="false"
默认为true,用于控制这个app是否开启硬件加速。
2、Activity级别:
activity android:hardwareAccelerated="false"
3、Window级别:(只支持开启操作)
getWindow().setFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
4、View级别:(只支持关闭操作)
view.setLayerType(View.LAYER_TYPE_HARDWARE, null);
LAYER_TYPE_HARDWARE ,使用硬件加速(GPU)进行绘制
LAYER_TYPE_SOFTWARE ,使用CPU进行绘制
或者布局文件中,指定以下属性:
android:layerType="software"
1、view.isHardwareAccelerated()
如果返回true,表示view挂在一个开启了硬件加速的Window之下,也就意味着,它在绘制时,并不一定开启了硬件加速。
2、canvas.isHardwareAccelerated()
如果返回true,因为着canvas在绘制的时候启用了硬件加速,尽量采用此方法来判断是否开启了硬件加速。
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流