Andorid Activity的本质是什么

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


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

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.

这句话概括的很好,但我并不认为这就是Activity的本质。


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

095942_R6bF_587661.png

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

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


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

不过这还不算完,还有一种情况,用户是半离开状态,什么是半离开呢,都知道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


转载于:https://my.oschina.net/yanquan345/blog/204193

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值