Android基础知识整理(一)

0.前言

android的基础知识很多,这里只简略的整理一些重点,参考资料结合自己的见解给大家讲讲,前面写了好多篇框架源码解析,这里就不唠叨源码了。

一、Handler

1.Handler、Looper、Message三者关系

(1)Handler:消息辅助类,主要向消息池发送消息和处理相应的消息(sendMessage和handleMessaage)

(2)Looper:不断循环执行从MessageQueue中读取消息,发送给目标处理

(3)Message:需要传送的消息,携带传送的数据

三者关系:

Looper不断循环从消息池中读取消息并分发消息给处理者,没有消息时进入阻塞状态;Handler调用sendMessage方法发送消息(Message)到消息池中,唤醒Looper,Looper不断从消息池中读取消息后调用消息的handleMessage方法处理消息。

2.MessageQueue数据结构

MessageQueue的数据结构为单链表,因其在插入和删除时比较有优势。主要用于向线程池投递消息和取走消息(即MessageQueue.enqueueMessage和MessageQueue.next)

3.子线程中创建Handler

要先调用Looper.prepare()方法,然后才能调用new Handler()创建Handler

4.Handler的Post原理

内部调用sendMessageDelayed()方法,传递使用getPostMessage方法将Runnable对象转换的一条消息。

在Handler的dispatchMessage方法中处理分发的消息时,会检查Message的callBack是否为空,为空则调用handleMessage方法,否则调用handleCallBack方法(此时已经切换到handler所在的线程),handleCallBack里面直接调用message.callback.run()方法,因此可以使用主线程创建的handler的post方法传递Runnable对象来更新UI。

二、Activity

1.启动模式

standard:标准模式,新建的Activity直接在栈中新建一个实例

mainfest中没有配置默认标准模式

singleTop(FLAG_ACTIVITY_SINGLE_TOP):栈顶复用模式,与standard模式相似,不同的是,如果被启动的activity位于栈顶,将直接复用它而不是新建实例。适用于登陆页面、推送通知等

singleTask(FLAG_ACTIVITY_CLEAR_TOP):栈内单例模式,栈内只有一个Activity实例,如果栈内已经存在此Activity的实例,在其他Activity中启动这个activity,将会直接把这个实例上面的其他activity踢出栈GC掉。适用于程序模块逻辑入口如主页面

singleInstance:堆内单例模式,整个手机操作系统里面只有一个实例存在。

适用于诸如来电显示、锁屏等系统应用

2.Intent中标志位设置启动模式

FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS:对应mainifest中属性为android:excludeFromRecents=true,当用户查看最近任务列表时该task将不会出现在最近任务列表中

FLAG_ACTIVITY_NEW_TASK:需要被启动的activity在manifest文件中配置taskActivity的值,则会在新标记的activity所在taskActivity中压入这个Activity

3.生命周期

正常:

onCreate():activity正在被创建,无法更新UI。

->onStart():activity后台可见,未出现在前台与用户交互

->onResume():activity前台可见

->onPause():activity正在被停止

->onStop():activity即将停止

->onDestroy():activity即将被回收

横竖屏切换:

onCreate()->onStart()->onResume()->onPause()->onStop()->onDestroy()->

onCreate()->onStart()->onResume()

设置configChanges:

onCreate()->onStart()->onResume()

4.Activity的启动流程

三、Fragment

1.生命周期

onAttach():Fragment与Activity关联之后调用

->onCreate():此时Activity的onCreate方法未执行,不能执行与Activity视图层相关的操作。

->onCreateView():自动关联View

->onActivityCreated():activity完成onCreate()回调之后调用,activity的视图层次结构已经准备好了

->onStart()

->onResume()

home:

onPause->onStop

恢复:

onStart->onResume

退出:

onPause->onStop

->onDestroyView:在视图层次结构与Fragment分离之后调用

->onDestroy:不在使用Fragment时调用

->onDetach:解除Fragment与Activity的绑定,释放资源

2.与Activity通信

(1)使用Activity对象引用:

通过接口,生成Fragment时回调Activity

通过传入ViewModel对象,通过ViewModel共享Activity,从而通过Activity实现通信

(2)Fragment Arguments

传递数据到Fragment中

//示例:在Activity中Bundle bundle=newBundle();bundle.putInt("Num",0);myFragment.setArguments(bundle)//在Fragment中获取Bundle bundle=getArguments()

方法与intent通过bundle传递数据类似

四、Service

1.生命周期

startService启动

onCreate()=>onStartCommand()

多次调用onCreate()只有第一次会执行,onStartCommand会执行多次;

stopService结束服务,执行onDestroy方法,并且多次调用stopService时,onDestroy只有第一次会被执行

bindService启动

当onBind()返回值为null时:

onCreate=>onBind

多次调用onCreate()和onBind只在第一次调用被执行。

不为空:

onCreate()=>onBind()=>onServiceConnected()

unbindService结束服务,生命周期执行onDestroy方法,并且unbindService只能调用一次,多次调用会抛出异常unbindService调用时一定要确保服务已经开启,否则会抛出异常。

2.startService和bindService区别

startService开启服务后,与Actively无关联,独立运行

bindService启动服务后,与Activity关联,推出时必须调用unbindService方法否则报ServiceConnection泄露错误。

五、广播Broadcast

1.NormalBroadcast默认广播

使用context.sendBroadcast()方法发送广播,异步接收,无法拦截

2.OrderBroadcast:有序广播

context.sendorderedBroadcast():每次只发送到优先级较高的接收者那里去,由高到低传送,优先级高的接收者有能力终止这个广播。

优先级:setPriority(int priority)

3.静态广播与动态广播

动态注册的动态广播是非常驻广播,随着Activity的生命周期变化需要注册和取消注册,当取消广播注册的代码所在的生命周期不执行时将引发内存泄漏和异常。

静态注册的静态广播是常驻广播,当程序退出后仍然会接受广播。

有序广播中,优先级高的先接收广播,优先级相同的情况下,动态广播优先于静态广播。

优先级相同的同类广播,静态广播先扫描到的优先于后扫描到的,动态广播先注册的优先于后注册的。且动态注册的广播仍然优先于静态注册的广播

4.广播注册流程:

静态注册

(1)扫描应用安装目录:调用PackgeManagerService.scanDirLi(),先扫描系统apk后扫描第三方apk

(2)解析apk:将上步骤扫描到的apk解析出Packge,并将AndroidManifest.xm中的BroadcastReceiver保持下来,按照顺序解析,因此注册顺序决定接收顺序

(3)保存广播:将广播保持到PackgeMannageService的mReceivers中

——可以通过PackgeManagerService.queryIntentReceivers查询intent对应的静态广播

动态注册

context.registerReceiver()

->(实际调用)AMS.registerReceiver

->mReceiverResolver.addFilter()

5.广播发送流程

context.sendBroadcast()

->ActivityManagerNative.getDefault()//即AMS

.broadcastIntent()

->AMS.broadcastIntentLocked:按顺序,先查询动态广播后查询静态广播

(因此动态广播优先于静态广播)

之后将广播包装到BroadcastRecord中放入BroadcastQueue中,

然后从队列中取出广播消息发送给BroadcastReceiver进行并行处理(如动态注册的非有序广播)和串行处理(如有序广播和静态广播)

为方便记忆,这里擅自作了张流程图:

广播注册.png

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

推荐阅读更多精彩内容