Andorid Activity的本质是什么

本文我主要经过查看Activity的实现源码和推测其设计思想的方法来探讨一下Android的本质是什么。
html


Activity恐怖是Android用得最多且是最基本的组件了,估计也是每一个学Android的人接触的第一律念,对于Activity的理解和说法,层出不穷,有人说是一个窗口,有个说是一个活动,但他的本质是什么呢,官方的说法是Activity一个应用程序的组件,它提供一个屏幕来与用户交互,以便作一些诸如打电话、发邮件和看地图之类的事情,原话以下:java

An Activity is an application component that provides a screen with which users can interact in order to do something, such as dial the phone, take a photo, send an email, or view a map.
android

这句话归纳的很好,但我并不认为这就是Activity的本质。数据库


切入主题以前,咱们先要了解一下UI系统的职责和原理。全部的图形界面,不管是什么UI系统,都要收集用户的活动,这些活动包括打开和关闭程序,输入事件等,这样系统才能针对这些活动作出一些反应,好比程序打开时加载一个数据库,创建一个网络链接,不过针对这些活动所做出的反应都委托给了具体的应用程序,系统至关于只是把这些事件或消息转发给应用程序。下面是一个简单的图:设计模式

这些消息怎么转发给程序呢,能够约定好,要求应程序写一个方法,或若是是C可要求传入一个回调,Java能够要求程序传入一个监听器,总之实现这个功能仍是很容易的,但这么多消息,所有传到一个方法里吗,我想那样会很惨,那样可能要求你写应用程序的时候可能要写一个长长的swich语句或if语句,因此通常都把这些消息分类,如一种是整个程序的活动的消息,如关闭和打开,还有就是输入事件,如按键鼠标,每一个分类里的消息还能够再细分,这样的话,就能够封装成多个类或接口,每一个类有数个方法,以后应用程序重写这些类方法或实现某个接口,系统就能够经过调用这些类或接口的实例发送消息了。网络

因而问题转化成了类的设计。在Windows中,有个窗口类来接受一个窗口的活动,系统就能够经过调用窗口类的方法来传递消息,这个窗口类既接受打开和关闭的活动,又接受用户输入事件。而在Android中而不一样,Activity只接受打开和关闭等的活动,而不会接受输入事件,那是由Activity内嵌的Window类来接受的,而后转发给相应View,你有可能会说Activity中有个onKeyDown方法,其实那只是处理没人领的按键消息才会到达Activity。如今发现Android和Windows分发消息的的区别了吧,这样化分,每一个类的职责更细了,更明确了,固然喽,Android中的消息跟Windows中的可能有点稍小的区别。app


如今应该能够很容易的理确Android的每个生命周期对应的方法(onCreate, onStart...)实际上是处理收到的消息,当用户打开一个Activity的时候,系统(严格的说应该是ActivityManager)就会调用onCreate来告诉你这个消息,这个时候你就要加载你的XML布局文件并作一些初始化。而后离开的时候,就应该把这个Activity销毁吗,若是用户是暂时离开,等下还要回来呢,若是销毁了那就又得重建立,太浪费时间了(用咱们家乡话说就是太难费神了),因此不能销毁,可是系统也得通知你用户离开了(用的是onStop方法),由于可能须要暂停播放视频。当下次从新进入的时候,系统又会通知你用户又进来了,这时你可能要恢复播放了,但你有没有发现,用户第一次进入和再次进入,你须要作不一样的处理,第一次多是初始化一些资源,第二次可能只要恢复播放就能够了,因此系统应该告诉你,是第一次进入仍是再次进入,因而系统就用了两个方法,用onCreate告诉你用户是第一次进入的,用onStart告诉你用户是再次进入。ide

不过这还不算完,还有一种状况,用户是半离开状态,什么是半离开呢,都知道Android的界在有全屏,仍是非全屏,也有半透明的,这里的半离开指的就是本界面被一个非全屏或半透明的界面盖住,总之,你还能看到一点点被盖的那个界面;全离开就是被全屏的界面盖住,用户彻底看不到被盖的。这两种状况要有可能要区别对待,好比一个播放在线视频的应用,它可能但愿要在用户半离开时只暂停播放,不暂停后台下载,而当用户彻底离开时,播放和下载都暂停。因此系统也应该区分这种状况,因而就有了onPause和onResume来表示半离开和从半离开恢复。值得注意的是,Android中全离开包括了半离开,半离开不包括全离开,什么意思呢,就是即使是全离开,系统也是先调onPause再调onStop,从全离开中恢复,也是调了onStart后还会调onResume,而对于第一次进入,onCreate、onStart、onResume会被依次调用,因此记住,只要用户进入,不管是怎么进入的,都是调用onResume,在这里恢复播放是再适合不过的了。还有一个onDestory也说一下,就是在销毁的时候被调用,通常是回收资源或按了返回键会被销毁。如今清楚了,也顺便看一下Android官网的这张图吧:函数


而后,你可能好奇系统是怎么调用到你写的onCreate方法的,有兴趣的能够查看源码的frameworks/base/core/java/android/app/ActivityThread.java,此类里面有许多handle***Activity方法,如handleResumeActivity,不过这不是本文章讨论的重点,后续有可能另写一篇讨论。布局

下面咱们来讨论一下Activity这个类吧,我估计不少人都忽略了Activity类也是一个类,它也能够有构造函数,你还能够在构造函数里初始化一些东西,不过请注意,Activity的onDestroy被调用时,Activity这个类自己尚未被销毁。还一点也不多人忽略,我常问应聘者Activity之间怎么通讯,他们通常都会说Intent或AIDL,若是两个Activity是同一个应用的,通常是运行在同一进程中的(除非你在AndroidManifest里配置了让它们不运行在同一进程),并且通常是同一线程的,因此最简单的通讯方法,莫过于在A Activity中写一个方法,让B Activity来调用,你再懒一点,直接访问变量均可以,只是风格很差。

其它,还要说明的是,一个Activity包含了一个Window,Window才是真正表明一个窗口,也就是说Activity能够没有Window,那正好是Service了,论据就是刚刚说的ActivityThread类,他的职责包括处理Service,(ActivityThread不是Thread的子类,但他描述了主线程要作的事,具体本文暂不讨论)。Window包含了一个DecorView,这才是真正的界面元素,它是整个View树的根,你能够试试在Activity里调用下面这句代码把整个界面染红:

getWindow().getDecorView().setBackgroundColor(Color.RED);


另外,还有一个ViewRoot,这个和DecorView常常有人搞混,首先是它对应的类的真正名字是ViewRootImpl,而后,他不是一个View,即他不是View的子类,他的工做与视觉元素无直接关系,但他肯定Android View系统的一个重要类,它是负责通讯的,若是你知道bridge设计模式就好理解了,这就是一个活生生的例子啊,不过不知道也不要紧,不会阻碍对下文的理解,负责谁跟谁通讯呢,是负责你的WindowManager与WindowManagerSerivce之间通讯,整个系统的窗口都是由WindowManagerSerivce管理的,由于全部窗口的Z-order,事件分发,都要由一个中枢统一管理才可能有秩序,这就是WindowManagerSerivce的职责了。这样说,你确定不能彻底理解,要理解仍是看代码吧,路径:frameworks/base/core/java/android/view/ViewRootImpl.java。其中有一句:

mOrigWindowType = mWindowAttributes.type;
                    res = sWindowSession.add(mWindow, mSeq, mWindowAttributes,
                            getHostVisibility(), mAttachInfo.mContentInsets,
                            mInputChannel);

就是向WindowManagerSerivce注册了一个输入事件处理监听器mInputChannel,具体实现能够写一篇很长的文章,暂不讨论。

这就是与Activity主要相关的信息,但愿本文加深了你对Activity的理解。


参考资料:

官网指南:http://developer.android.com/guide/components/activities.html

相关文章
相关标签/搜索