Android部分技术点目录(2)

目录

Toast可以在子线程使用
估值器和插值器
Activity启动过程
Intent能传递的数据类型
Parcelable和Serializable区别
Instrumentation
WMS和AMS的窗口切换过程
ListView局部刷新
Android中App的内存大小、largeHeap的大小
在onCreate中用子线程给TextView属性赋值成功的问题
性能分析工具
线性布局的几个问题

Toast可以在子线程使用

Toast是系统Window,不受ViewTree刷新时checkThread的限制。
但是Toast不能随便在子线程使用,需要子线程启动Looper,或者是handlerthread。
因为toast需要让notification manager service 回调自己,这是通过bindler回调的,回调会进入Bindler线程,不是直接回到发起toast的线程,这就需要该线程有looper,这样才能用handler通知到调用Toast的线程。

估值器和插值器

估值器和插值器是用于属性动画ObjectAnimator的,原理是不断调用get和set方法来重设属性值,比补间动画的形式更加丰富。
属性动画中的估值器和插值器,是实现非匀速动画的,根据当前属性改变的百分比,计算改变后的属性值。
插值器Interpolator决定变化的趋势,可以根据时间流逝的百分比,计算属性改变的百分比。
估值器Evaluator设置变化的具体数值,让属性值从初始值过渡到结束值。
过程插值器根据input的时间,计算出属性变化的百分比fraction,插值器根据百分百fraction,结合动画的初始值startValue和结束值endValue,计算出当下的属性值
大致流程如下:

属性动画工作流程

属性动画中的插值器和估值器

Activity启动过程

1.Activity中最终到startActivityForResult()(mMainThread.getApplicationThread()传入了一个ApplicationThread检查APT)
->Instrumentation#execStartActivity()和checkStartActivityResult()(这是在启动了Activity之后判断Activity是否启动成功,例如没有在AM中注册那么就会报错)
->ActivityManagerNative.getDefault().startActivity()(类似AIDL,实现了IAM,实际是由远端的AMS实现startActivity())
->ActivityStackSupervisor#startActivityMayWait()
->ActivityStack#resumeTopActivityInnerLocked
->ActivityStackSupervisor#realStartActivityLocked()(在这里调用APT的scheduleLaunchActivity,也是AIDL,不过是在远端调起了本进程Application线程)
->ApplicationThread#scheduleLaunchActivity()(这是本进程的一个线程,用于作为Service端来接受AMS client端的调起)
->ActivityThread#handleLaunchActivity()(接收内部类H的消息,ApplicationThread线程发送LAUNCH_ACTIVITY消息给H)
->最终在ActivityThread#performLaunchActivity()中实现Activity的启动完成了以下几件事:
2.从传入的ActivityClientRecord中获取待启动的Activity的组件信息
3.创建类加载器,使用Instrumentation#newActivity()加载Activity对象
4.调用LoadedApk.makeApplication方法尝试创建Application,由于LoadedApk只有package一个单例所以不会重复创建。
5.创建Context的实现类ContextImpl对象,并通过Activity#attach()完成数据初始化和Context建立联系,因为Activity是Context的桥接类,
最后就是创建和关联window,让Window接收的事件传给Activity,在Window的创建过程中会调用ViewRootImpl的performTraversals()初始化View。
6.Instrumentation#callActivityOnCreate()->Activity#performCreate()->Activity#onCreate().onCreate()中会通过Activity#setContentView()调用PhoneWindow的setContentView()
更新界面。

启动流程

Intent能传递的数据类型

Intent可能需要跨进程传递数据,所以传递的最终类型都是Parcelable或Serializable,Intent开放的Bundle、和Intent自身都是Parcelable对象,向Intent里传值其实都是Bundle处理的,包括CharSequence、Serializable等。

Intent能传递的数据大小

Intent其实是走Binder机制,内存对Binder的mmap限制为4M以内,实际App层限制为1M~8K,所以Bitmap过大就会崩溃。

Parcelable和Serializable的区别

虽然都做序列化,但是实现方式和用途不同:
1.实现方式
Parcelable需要手动实现writeToParcel和CREATOR的createFromParcel。
Serializable只需要实现Serializable接口即可,同时允许扩展功能,比如可以利用transient关键字,声明某些属性不允许序列化;可以利用serialVersionUID属性来区分各版本数据;可以利用readObject和writeObject,介入序列化和反序列化过程,这可以用来规避破坏单例的问题。
2.序列化对象和读写
Parcelable是Android特有的,序列化为Parcel对象,可以marshall或unmarshall为byte[]数组,通过操作native指针来实现快速读写和。
Serializable是Java通用的,序列化为Stream字节流,会有大量的IO操作,还会执行反射,会产生很多中间变量,既有GC压力,又占用内存,速度也慢。
3.应用场景
Parcelable更高效,但通用性差,Parcelable通过native方法操作内存指针,效率很高;但是Parcelable通用性差,不建议存为文件或通过网络传输,虽然Parcelable也能持久化数据,但是Parcelable在各android版本上差异大,在数据转换上会有问题。

Instrumentation

是ContextImpl中的对象,每个App只有一个Instrumentation对象,每个Activity通过引用Context引用这个Instrumentation对象,这是App进程的管家,ActivityThread都是通过Instrumentation来处理创建、暂停Activity等处理。

ListView局部刷新

ListView有时候只有一个item发生了变化,如果要只更新这1个item,需要三步:
1.找到item,用数据列表的index,减去mList.getFirstVisiblePosition(),可以判断是否正在显示区间内,然后用mList.get(index-firstVisiblePosition),可以找到item的View
2.取出ViewHolder,通过view.getTag(),获取到ViewHolder
3.更新界面,直接在ViewHolder中修改item的界面

Android中App的内存大小、largeHeap的大小

查看设备的/system/build.prop文件
dalvik.vm.heapstartsize=8m App初始大小
dalvik.vm.heapgrowthlimit=192m 普通App的上限
dalvik.vm.heapsize=512m largeHeap的App的上限
探究android:largeHeap

在onCreate中用子线程给TextView属性赋值成功的问题

判断主线程UI是在viewRootImpl中的checkThread进行的,如果View还没有绘制出来,就会先做属性赋值,然后才会做invalidate绘制,那么checkThread就是在子线程赋值之后执行,其实还是在主线程绘制的。
所以,因为在onResume之后,Activity的PhoneWindow的DectorView的viewRootImpl才会被生成,所以在onCreate里赋值时不会触发invalidate绘制。
为什么我们可以在非UI线程中更新UI

性能分析工具

一、DDMS(MAT)检测内存泄露;
二、TraceView跟踪代码执行时间;
三、Dump UI Hierarchy for UI Atomator分析UI层级;
四、Systrace追踪系统中各子系统的运行状态;
分别简述:
一、DDMS+MAT检测内存泄露;
Dalvik Debug Monitor Service是一个程序执行查看器,能看到线程和堆栈等信息。
DDMS其实是用端口监听测试终端,用adb建立调试器,发送指令到调试终端。
DDMS本身提供了一个简便的Heap工具查看有没有内存泄露现象,通过CauseGC,检查多次操作后内存是否稳定。
如果发生了内存泄露,就收集内存使用信息,导出为.hprof文件,用MAT工具去打开文件(继续转换一次,转为标准hprof文件),详细分析。
MAT的饼图没啥作用,主要看Histogram,过滤出所有对象,列出内存中的对象列表,检查每个实例的Path to GC Roots,exclude所有的weak/soft引用,找到这些对象都是被哪个对象引用,从而推断出内存泄露的原因。
二、TraceView跟踪代码执行时间;
TraceView是性能分析器,能查询代码执行时间。
1.分析具体代码块
首先,在代码中插入trace标记:
android.os.Debug.startMethodTracing("保存文件名");
android.os.Debug.stopMethodTracing();
注意要在manifest里允许读写文件,系统会把数据保存到文件里/mnt/sdcard/保存文件名.trace'
然后,用Monitor工具(sdk/tools/monitor.bat)导入trace文件,进行分析
2.分析App的某个操作
首先,记录操作数据,利用AS自带的Monitors工具,点击CPU一栏中秒表logo的标记开始trace,然后操作App,操作完成后,结束trace。
然后,分析数据,TraceView提供了调用的函数、各函数的执行时间和次数等。
正确使用Android性能分析工具——TraceView
Android系统性能调优工具介绍
三、Dump View Hierarchy for UI Atomator分析UI层级;
DDMS里在截屏按钮后面有个Dump View Hierarchy按钮,可以在DDMS中刷出当前app的页面,选择某个元素,就能列出其所在的UI层级等信息。
四、Systrace追踪系统中各子系统的运行状态;
Systrace功能非常强大,可以对CPU、Native进程甚至Kernel线程采集性能数据。
在DDMS中练好设备,点击最右侧统计形状的按钮,设置输出文件地址和要采集的内容,输出一个html文件,打开是张统计报表(只能用chrome浏览器打开,其他浏览器如Safari打开是空白)
Android性能优化工具之Systrace

线性布局的几个问题

线性布局中,两个Button,如何分置两边
利用android:layout_weight=“1”来填充剩余空间,可以中间插一个透明,也可以嵌套一层。
五种布局:LinearLayout、RelativeLayout、FrameLayout、AbsoluteLayout、TableLayout

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,445评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,889评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,047评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,760评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,745评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,638评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,011评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,669评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,923评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,655评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,740评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,406评论 4 320
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,995评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,961评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,023评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,483评论 2 342

推荐阅读更多精彩内容