了解了整体的android创建流程之后,就分析一下到底这个过程中做了什么?
activity创建中开始时由activityStack中的realstartActivityLocked函数中调用了activityThread中的scheduleLaunchActicity,然后利用H发送消息调用handleLaunchActivity,由此就开始了创建activity的全过程。
创建和生命周期:
1.在handleLaunchActivity中调用了performLanuchActivity:
tip:其中有一个ActivityClientRecord,这个是activity的一个数据对象,里面有创建activity的数据,创建activity就需要他,同时在服务程序中ActivityStack中使用的是ActivityRecord。
这个函数中执行:加载packageinfo的信息,也就是你的包的信息,创建程序总有一些配置和管理的package信息。获取CompontName,这个是用来匹配启动activity的信息的,然后就是利用Instramentation创建出activity的实例。
tip:这里的Instramentation就是专门去管理activity的操作类,里面包括了创建activity和调用activity的生命周期方法。这个时候会考虑既然activityThread就是管理activity的为什么还要有一个Instramentation?其实,这样考虑,avtivityThread相当于是actvity的主人,主要负责管理activity的生命周期和外界的交互。但是Instramentation仅仅是一个管家,他要做的是就是activity紧密相关的。avtivityThread做的更加广,Instramentation做的更加细致。
这个时候要考虑一个问题,创建出来activity,就是我们的activity了吗?他仅仅是一个类而已怎么和app的生命关联在一起的呢?接着又做了一件事,利用Instramentation创建了application,这也是一个对象而已,又是怎么成为app全局存在?重点在于Context,context是上下文的意思,是整个进程的运行环境依赖,也就是运行时候的重要数据和操作资源的入口。所以要是和Context联系在一起,就变得不是寻常的类,这个时候无论activity和application都用了attach函数,就是挂在和自己相关的context。
tip:又有一个常见的问题出现了application context 和activity context 一样吗?不一样,我们看源码可以发现者两者的Context都是new出来并且都是ContextImpl对象,虽然不一样,他了的不同之处到底在哪里?全局只有一个application,但是每一个activity都有一个context。在创建ContextImpl的时候要传递参数有3个:loadedapk,binder,activityThread。loadedapk就是加载和处理包信息的。创建的时候只有binder对象传的不同,这个binder是用来和activityMangaerService交互的。application创建的时候没有传递这个参数,所以注定了application Context是和activity无关的,也就说:在和activity相关的类使用activity Context,其他情况都可以。但是application Context的域范围更加广泛。
这也就有一个activity中内存泄露的问题,activity context只在其生命周期有效,假如被外界利用了,并且保存了引用,如果要是activity 被销毁了,但是Context内存并不能释放,长期运行下去,一定会有问题。所以合理的使用Context对于运行时间长的app一定要注意。这个时候就
有了一个application的使用技巧:到底application可以做什么?一般来说application是全局的,我们可以利用application来数据交互,也就是在application定义一些数据集合比如hashmap,list之类,由于数据时贯穿app生命中的,所以每一个activity都可以使用。还有就是定义一些全局的广播接收者,接收全局数据或消息,还有一个用处就是定义一个Activity的stack,由于有时候需要关闭所有的activity.利用stack来保存。还有一个用处就是捕获全局的一场,其实Thread就有一个可以捕获线程异常的方法Thread.setDefaultUncaughtExceptionHandler(handler),但是activity的生命有限,application是整个生命周期的,正好可以用来做这个。
又有一个问题产生了,在多个activity的时候会使用抽象一个父类baseactivity,为什么不在baseActivity中做呢?当你产生一个异常的时候重启应用会把之前的数据清空了,所有的数据都会丢失掉,但是在application中的数据不会。我不知道这个重启的操作中做了什么,但是实验就是这个结果,以后如果看源码知道了在贴出。
挂在Context在application和actvity对象上,activity的attach方法更加复杂一些,要创建phonewindow等操作。之后会设置activity的主题Theme。接着就调用Instramentation调用了oncreate。然后会调用performStart,也就是onStart,所以感觉这个onstart方法十分鸡肋,oncreate和onstart之间并没有什么特殊动作,我感觉onstart是为了更加明确的分辨activity的生命周期。这也就是之后我们要讨论为什么这么划分生命周期?然后看一下是否是重启应用也就是之前的一个state中有无数据,有的话就要调用onRestoreInstanceState() 到处两个生命周期方法就结束了。
tip:其中为了明确分辨到底是处于什么生命周期,用的就是boolean的标志,有mCalled这个主要的作用是到底调用了activity的方法没有比如你的activity中没有用super.onCreate()那么就会有一个runtime异常。来强制你调用父类。还有一些mStoped,mPaused,mResume,mFInished都是用来标示生命周期的。
2.接着调用了HandlResmeActivity,里面有performResumeActivity:
检查一下r.pendIntent是否要执行onnewIntent,也就是当你是singletask模式的时候,会直接执行这个方法。然后调用了performResume,也就是onResume,这时候设置paused,stoped为fasle,进入了可交互时期。然后会挂载我们的布局。
到此为止创建activity的生命周期方法就都完成了,我们可以看到一个activity有些什么?父类和接口是一个可以做的动作的表现形式,Context,window和key的callback等,所以activity一定可以处理和调用当前应用系统的资源,处理window和key的事件,也就是处理用户交互的动作包括按键和触屏。实际上着也就是actvity要做的事情,在创建的生命周期中做好这些处理,挂在Context,然后生成phonewindow利用里面的viewroot进行用户交互(按键和触屏)。当然我们要联系所有app应用的调用,当一个actvity不显示的时候,也就是被覆盖了,你就不可以和用户交互了,失去焦点了。一定要有onPause,当你的activity界面消失,不是销毁。比如按了home。就要调用onstop,但是没有调用ondestory,这是因为在产生activity的时候要创建一系列类要和AMS(activityMangerService)交互,这个过程很麻烦,很可能我还要在开启这个应用,那么我索性就不销毁了,等到下一次直接onstart就可以。所以这也就是onstart的作用,这个动作是一定要有的,在查看源码的时候要考虑用户交互和效率的问题。
所以生命周期函数实际上就是诠释了activity的交互流程,什么时候该销毁,什么时候该消失,什么时候失去焦点。
3然后我们就说一下对应的结束调用,实际上后面的这几个动作就是为了销毁时候做好收尾动作
finish的时候,ActivityManagerNative告诉ctivityMangerService在调用activityStack发送消息给activityThread的HandleDestoryActivity,然后依次调用onSaveInstanceState,onPause,onstop,ondestory.其中没有什么特殊操作,仅仅是方法调用而已。设置标志位mstoped,mpasued等
tip:其实还有一个疑问就是调用生命周期函数onstart,onrestart,onresume,onstop时候都要调用Activity的performXXX然后回调Instramentation的callActivityonXXX,但是唯独onpause是直接调用的Instramentation的方法。并且其他的操作都只是判断一下mCalled也就是调用了父类没有,但是onpasue里面还要检测是否当前sdk版本和os的sdk版本是否一致,这个让我很困惑,到底为什么?(未解决)
4最后简单的说一下Activity的显示模式:一共有四个standard,singletop,singletask和singleInstance。其中特殊一点的就是singleIntance,在系统服务中会保存各种的actvity的启动和销毁的信息,就比如历史启动的信息HistoryRecord,都有一些栈。但是运行的栈也是不同的,之前的模式都是在一个栈结构里面,但是singleInstance是单独的栈结构。浏览器就是这种模式,主要是为了所有的应用都可以使用这个实例。而singletask也有一点特殊,就是他是只有一个实例,但是不会开任务栈,假如有该实例,就会把在他上面的栈元素都清空。这个两种都是很单一的实例。但是特性是不同的。在设计界面交互的时候一定要考虑好跳转关系,actvity的调度顺序一定要优化好。通常现在的应用不会产生很多activity,而是使用在同一个界面中的选项卡来进行交互。这样很好的处理了跳转逻辑,但是一定要处理好跳转的信息处理。有利有弊。
Activity 和 生命周期: 创建的更多相关文章
-
Android开发之Activity的生命周期以及加载模式
本篇博客就来好好的搞一下Activity的生命周期,如果搞过iOS的小伙伴的话,Activity的生命周期和iOS中ViewController的生命周期非常类似.生命周期,并不难理解.一个人的生命周 ...
-
Activity的生命周期
Activity的生命周期 以往我们实现页面间的跳转都是实例化Intent类的对象,但是页面在我们眼前的出现与消失没有我们所看到的那么简单,它有一个复杂的生命周期,一个页面的出现,被覆盖,再次出现,被 ...
-
浅谈Android中Activity的生命周期
引言 我想对于Android开发人员来说,Activity是再熟悉不过了,今天我们就来探讨下Activity的生命周期.熟悉的掌握Activity对于开发健壮的Android应用程序来说至关重要.下面 ...
-
每天一点Android干货-Activity的生命周期
Activity Activity是这样一个程序组件,它为用户提供一个用于任务交互的画面. 一个应用程序通常由多个activity组成,它们彼此保持弱的绑定状态.典型的,当一个activity在一个应 ...
-
Android中Activity的生命周期
简介: 这个基本是必问的问题了,说一下你对Activity生命周期的理解,呵呵… onCreate, onStart, onResume, onPause, onStop, onDestroy, on ...
-
Android Activity的生命周期简单总结
Android Activity的生命周期简单总结 这里的内容参考官方的文档,这篇文章的目的不是去总结Activity是如何启动,如何创造,以及暂停和销毁的,而是从实际开发中分析在Activity各个 ...
-
Android之Activity的生命周期
PS:写一发关于Activity的生命周期,也算是面试的重点内容. 学习内容: 1.Activity的生命周期 2.面对多种情况的时候Activity的生命周期 3.onSaveInstanceSta ...
-
十分钟掌握Activity的生命周期与启动模式
1. Activity的生命周期 正常情况下的Activity生命周期如下图所示(来自Android Developer): 当资源相关的系统配置变更时(比如设备屏幕方向改变,键盘可见性变化),会导致 ...
-
无废话Android之activity的生命周期、activity的启动模式、activity横竖屏切换的生命周期、开启新的activity获取他的返回值、利用广播实现ip拨号、短信接收广播、短信监听器(6)
1.activity的生命周期 这七个方法定义了Activity的完整生命周期.实现这些方法可以帮助我们监视其中的三个嵌套生命周期循环: (1)Activity的完整生命周期 自第一次调用onCrea ...
随机推荐
-
用c#开发苹果应用程序 xamarin.ios方式
NetworkComms网络通信框架序言 Networkcomms网络通信框架来自于英国,支持以xamarin.ios的方式开发苹果应用程序 其开源版本2.3.1中带有一个示例程序,实现聊天功能,只要 ...
-
php面向对象(二) $this
<!doctype html> <html> <head> <meta charset="UTF-8"> <title> ...
-
(转载)mysql书籍
(转载)http://blog.csdn.net/symdfbb/article/details/7636332 MySQL技术内幕 mysql使用大全,可以说方方面面都包括了.认真研读大概一本就差不 ...
-
数据结构(线段树):CodeForces 145E Lucky Queries
E. Lucky Queries time limit per test 3 seconds memory limit per test 256 megabytes input standard in ...
-
sizeof操作符-结构体与类大小
导读 sizeof是C/C++一个难点,当在自定义类上应用sizeof操作符时,总会出现意想不到的结果,下面,我们就来探讨一下sizeof这个操作符! 目录 1. sizeof与strlen的区别 2 ...
-
【javascript】ajax的参数
1. 常用参数 url type: contentType: dataType: data: success: error 2. 特殊参数 context: 这个对象用于设置Ajax相关回调函数的上下 ...
-
MongoDB-python的API手记
-------------------python调用MongoDB------------------- 1.官方文档:http://api.mongodb.org/python/current/t ...
-
iframe实用操作
iframe高度设置为子页面高度 //需要使用Jquery $(document).ready(function () { parent.document.getEleme ...
-
PostgreSQL(一)教程 -----高级特性
一.视图 假设天气记录和城市为止的组合列表对我们的应用有用,但我们又不想每次需要使用它时都敲入整个查询.我们可以在该查询上创建一个视图,这会给该查询一个名字,我们可以像使用一个普通表一样来使用它: C ...
-
CentOS下的apache配置支持php
修改Apache的配置文件httpd.conf(vi /etc/httpd/conf/httpd.conf) DirectoryIndex index.html index.php #添加index. ...