activity 和 生命周期 :流程
activity是android的一个基本的组件。讨论生命周期,taskstack等等的话题的时候。就不得不去看一下android framework层的源码了。
生命周期,实际就是系统调用android代码的时候做的回调函数,复写之后,就会和android app运行为一体。简单的来说,和activity有关的类有很多。其中和生命周期有关的,就是管理activity的类。包括activityThread,activityManagerNative,activityManagerService 和activityStack:
activityThread: 每一个java程序都有一个main函数,android也不例外。每一个app都是一个进程,这里既是一个app的起始点。gui的编程无非就是在循环中不断的读取消息,然后处理消息。这里的消息包括了各种系统定义的消息,还有ui的消息。activityThread里面有一个H内部类(就是Handler),这里面就定义了各种的消息处理,包括各个生命周期函数的方法调用消息:LAUNCH_ACTIVITY,PAUSE_ACTIVITY等等。
tip:为什么会有H内部类?假如有了这个疑问,就是没有体会gui编程的本质。消息循环,android开发我感觉弱化了这一概念。假如没有消息循环,窗口就不能判断各种事件,不能作出处理。细想一下,只有响应式的这种设计,才是gui编程的基本原理。没有其他可以代替。所以Handler处理的消息机制是android ui运行的基本ok,这个毋庸置疑了。H存在是合理的不可替代的。为什么会有activityThread?他的出现实际上就是作为消息循环的框架出现的。管理了框架中的各个元件的管理和生成,android4大基本组件activity,service,provider都在activityThread中管理。所以activityThread存在是必然的。
activityManagerNative和activityManagerService:他两个出于不同的包里面,一个是core的app下,一个是services的am包下。来说一下,activityManagerService是zygote创建系统服务,也就是说这个服务和我们的android app是两个进程之间。android的ipc通信使用的是binder机制。这个机制也是android的核心之一,也就是通过activityManagerNative调用了activityManagerService里面的方法,调用了系统功能。
tip:他两的存在性就不必强调了,多任务系统的进程通信一直都是值得关注的问题。而binder机制提供了这种功能。这两个类的作用就是使得app和系统更加有序的交互。
activityStack:栈,是的这个就是activity栈,他也在系统服务包中,说明这个栈管理的是所有的activity的功能。所有的存在的activity都会存储在这个栈中,里面有历史栈,resume栈等,保存着各种的activity操作信息。
tip:activitystack由于android程序一般都是占满屏幕的,所以切换不易,必须要有一种操作的规律和习惯。栈是人们潜意识中很认可的一种结构,android是基于linux支持多进程很好。windowphone7.5的时候就一般了,而且操作很不习惯。玩了很久才弄明白。但不得不说metro风格确实是一大亮点。
解释完这些,我们就了解了android activity的生成过程,细想一下,是通过intent开开启activity的,调用了startActivity,有一个activity的默认操作类Instrumentation来调用了activityManagerNative,然后通过binder调用activityManagerService的方法调用activitystack的管理方法添加activity,启动actvityThread,然后发送消息给H进行显actvity。
在说说生命周期,整个期间是如何进行回调的?其中的调用过程十分复杂,我想我必须研究的足够的时候在写其中的奥妙,可是还是没有完。遇到了一个问题就是在oncreate中想得到view的宽高。网络上有很多方法,但是只有知道系统的调用原理和流程,才会理解为什么那样做。
首先不说如何解决?说一下为什么oncreate中得不到view的宽高?都知道view绘制有3步:测量,布局,绘制。也就是oncreate的时候view就没有做这几个步骤。那setcontentview中做了什么?
回到生命周期:
onreate和ondestory中是指activity被创建了,也就是初始化的时候的回调,这个时候做的都是初始化工作,setcontentview也仅仅就是解析xml然后进行了view的创建。但是布局和大小信息都不确定。
onstart和onstop中指的activity被显示,这个看似是很鸡肋的,我们都没有多使用过,确实,这个时期,就是显示了actvity的窗口,activity可视了。这时候可以layout测绘了?没有,这时候显示的是除了我们setcontentview里面布局之外的东西,也就是有一个actionbar和一个白色背景,当然这要看你的布局是怎么定义的了。这算什么意思?这些布局不都是一起的吗?为什么没有我设置的?细细想,还确实不是一起的,先不谈phonewindow和decorview,我们定义过titlebar没有?没有,这是系统的,实际上这一时期是为了显示activity的,不做其他的。
onresume和onpause指activity在可以交互,坑爹的时刻到了,大多数人认为这个时期一定是加载了我们的布局,实际上在这个时期是要使得布局和前台进行交互,但是在布局测绘之前系统回调了onresume,导致很多人认为onresume之前一定有layout的测绘信息,这个是错误的。你可以查看源码activityThread中关于handleResumeActivity里面的源码,最后调用了activity的makeVisible进行了view的显示。也就是说这一个时刻仅仅是告诉我们actvity要到前台交互的时候了,千万不可和布局的东西混为一谈。
这也就说明了为什么会出现之前的问题,这时候怎么办?所有生命周期的函数都没有在layout的时候调用的,没有生命周期的函数,我们还有回调函数,其实view有一个getViewTreeObserver,可以再viewtree的回调函数中进行值的获取,这种方式是可行的,也就是等到测绘layout之后在进行取值,当然还有一种就是自己进行测绘,利用measure,有的人说不行,实际上他根本就不会使用measure,MeasureSpec是其中的关键,他如何利用一个int来表示了模式和大小两个状态,不明白一共有3种模式,一味的递参数(0,0)那么只能呵呵了。这种方式是可行的,我会在以后view的绘制中专门叙述这些概念。
其实我是想说另一种方式,我在网上没有看到,可能有人实现过。就是使用view.post来进行一个把runnable的方法放到主线程中运行,这个方法可行吗?其关键就是这个代码什么时候执行?是立刻?不是,既是在oncreate中使用这个也会在onresume之后运行,这实际上把一个消息放入消息循环中,由于消息队列是阻塞式的,当执行完所有的显示activity的方法之后才会执行这个消息。做了大量的实验。证明这一点事毋庸置疑的,所以我认为系统创建的消息包括launchactvity和resumeactivity的一些消息一定是view.post这条消息之前的,实际上我尝试源码中的证据,你可以看到的是只看到了H.LAUNCH_ACTIVITY这一个消息(虽然也有H.RESUME_ACTIVITY但是在初始创建期间不会调用),也就是说这个消息处理函数handleLaunchActivity里面执行完了oncreate,就接着执行了onstart和onresume一系列的生命周期函数,并不是每一个回调都作为一个消息。这的理由是合理的:1.你不必使用多个消息,应为这个过程本身就是连续的(当然我指的连续不是代码上的连续,而是逻辑上的连续)。2.这也就是解释了为什么在oncreate里面提交的消息,会在onresume之后执行。
当然这个问题就算解决了,应该思考的不是这个问题,而是android的这些生命周期的是如何协调的?可以看到生命周期是和用户交互最为紧密的。我会在研究源码的同时把后续blog写出来。
activity 和 生命周期 :流程的更多相关文章
- Android之Activity的生命周期
PS:写一发关于Activity的生命周期,也算是面试的重点内容. 学习内容: 1.Activity的生命周期 2.面对多种情况的时候Activity的生命周期 3.onSaveInstanceSta ...
- 浅谈Android中Activity的生命周期
引言 我想对于Android开发人员来说,Activity是再熟悉不过了,今天我们就来探讨下Activity的生命周期.熟悉的掌握Activity对于开发健壮的Android应用程序来说至关重要.下面 ...
- Activity 和 生命周期: 创建
了解了整体的android创建流程之后,就分析一下到底这个过程中做了什么? activity创建中开始时由activityStack中的realstartActivityLocked函数中调用了act ...
- activity的生命周期详解
刚在看mars老师的视频,看到activity的生命周期,就看了一下,总结了一下.下面是各函数的调用时机 为了更清楚的看清楚工作的具体过程,举例如下: ,建立两个activity,一个main,一个a ...
- Activity的生命周期和启动模式
Activity的生命周期分析 典型情况下的生命周期.是指在用户参与的情况下,Activity所经过的生命周期的改变. 异常情况下的生命周期.是指Activity被系统回收或者由于当前设备的Confi ...
- Android开发艺术1之Activity的生命周期
作为<Android开发艺术探索>这本书的第一篇博客,我就多说几句.本系列博客旨在对书中相关内容进行解读,简化,提供一个入门到提高的流程.不敢说书评,也不能说教程,只希望对有些人有帮助就好 ...
- Android开发之漫漫长途 Ⅰ——Android系统的创世之初以及Activity的生命周期
该文章是一个系列文章,是本人在Android开发的漫漫长途上的一点感想和记录,我会尽量按照先易后难的顺序进行编写该系列.该系列引用了<Android开发艺术探索>中的相关知识,再次表示该书 ...
- Android开发艺术探索笔记——第一章:Activity的生命周期和启动模式
Android开发艺术探索笔记--第一章:Activity的生命周期和启动模式 怀着无比崇敬的心情翻开了这本书,路漫漫其修远兮,程序人生,为自己加油! 一.序 作为这本书的第一章,主席还是把Activ ...
- Android开发学习之路--Activity之生命周期
其实这篇文章应该要在介绍Activity的时候写的,不过那个时候还不怎么熟悉Activity,还是在这里详细介绍下好了.还是参考下官方文档的图吧: 从上面的流程,我们可以看出首先就是打开APP,开始执 ...
- Activity 之生命周期
Activity 之生命周期 本文内容: 1. Activity 介绍 2. Activity 的生命周期 2.1 生命周期图 2.2 常见情况下生命周期的回调 2.3 关于生命周期常见问题 2.4 ...
随机推荐
- [转]C#中调用资源管理器(Explorer.exe)打开指定文件夹 + 并选中指定文件 + 调用(系统默认的播放类)软件(如WMP)打开(播放歌曲等)文件
原文:http://www.crifan.com/csharp_call_explorer_to_open_destinate_folder_and_select_specific_file/ C#中 ...
- 【Tomcat】Tomcat Session在Redis共享
参考的优秀文章 Redis-backed non-sticky session store for Apache Tomcat 简单地配置Tomcat Session在Redis共享 我使用的是现有的 ...
- 【Unity3D游戏开发】之利用语法糖添加自定义拓展方法(下) (十八)
首先需要声明的是“语法糖”这个词绝非贬义词,它可以给我带来方便,是一种便捷的写法,编译器会帮我们做转换:而且可以提高开发编码的效率,在性能上也不会带来损失.这让java开发人员羡慕不已,呵呵. 1. ...
- 手机号码归属地查询api接口
淘宝网 API地址: http://tcc.taobao.com/cc/json/mobile_tel_segment.htm?tel=15850781443 参数: tel:手机号码 返回:JSON ...
- MultiProvider
声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...
- max-width实现图片的自适应
在自适应布局中,有时候会让图片随着宽度的变化相应的放大或者缩小,或者说让图片等比缩放,但是每个图片的大小又不一样,这个时候我们就要用到max-width这个属性了. img{ max-width:10 ...
- C++用PostMessage模拟按钮点击
有时我们可能会在某个程序中用到模拟按钮点击事件. 本文中的例子在MFC程序中调试通过,duilib的没试过,还需探索 不多说,上代码: #include "stdafx.h" #i ...
- js修改:before、:after的内容
一.js控制伪元素content内容 二. --------------2016-7-20 13:34:03-- source:[1]js如何控制伪元素的内容
- springMVC,mybatis配置事务
首先应该对context:include-filter和context:exclude-filter有一个了解,include是包含这个,而不是只包含,下面会有例子看看: 这是我最开始配置的MVC的配 ...
- windows下开启mysql远程访问
USE mysql;SELECT * FROM USER ; 直接修改user=root host=127.0.0.1为% FLUSH PRIVILEGES;