(一)前言
在以前一篇帖子讲ams的时候,提了一下TabActivity。当时说它比较特殊就没有下文了,今天重发一篇帖子,跟大家探讨一下TabActivity。
做个假定先: 比如我们最外面的Activity是MainActivity, 第一个tab是FirstActivty, 第二个tab是SecondActivity .
相信大家都用过TabActivity, 它是一个特殊的Activity,它特殊的地方在哪里?有以下几点为证:     
a. 它看起来违反了Activity的单一窗口的原则。因为它可以同时加载几个activity, 当用户点击它上面的tab时,就会跳到相应的Activity上面去。
b. 用户首先进去FirstActivity,然后进去SecondActivity,再点击返回键的时候。它返回的界面不是FirstActivity,而是退出我们的应用程序。
c. 当用户在FirstActivity按返回键的时候,如果MainActivity和FirstActivity通过重写onKeyDown()方法,那么收到事件回调的只有FirstActivity。

(二)TabActivity存在必要性以及google当时的困扰
a. 首先我们要明白一点,android系统是单窗口系统,不像windows是多窗口的(比如在windows系统上,我们可以一边聊QQ,一边斗地主等等)。也就是说,在一个时刻,android里面只有一个activity可以显示给用户。
这样就大大降低了操作系统设计的复杂性(包括事件派发等等).
b. 但是像TabActivity那种效果又非常必要,用户体验也比较好。所以我觉得当时google开发人员肯定很纠结。。 于是,一个畸形的想法产生了,就是在单窗口系统下加载多个activity,它就是TabActivity。

(三)TabActivity实现加载多个Activity原理
我们都知道,想启动一个Activity,一般是调用startActivty(Intent i)方法。然后这个方法会辗转调用到ams(ActivityManagerService)来启动目标activity.
所以,TabActivity实现的要点有两个:
a. 找到一个入口,这个入口可以访问到ActivityThread类(这个类是隐藏的,应用程序是访问不到的),然后调用ActivityThread里面的启动activity方法
b. 绕开ams,就是我们TabActivity加载的FirstActivity和SecondActivity是不能让ams知道的。
所以,一个新的类诞生了 ---- LocalActivityManager , 它的作用如下:
1.  这个类和ActivityThread处于一个包内,所以它有访问ActivityThread的权限。
2.  这个类提供了类似Ams管理Activity的方法,比如调用activity的onCreate方法,onResume()等等,维护了activity生命周期, 和ams相比,就像西游记里面的大雷音寺和小雷音寺一样。
    也正如其名字一样,它是本地的activity管理。就是说它运行的进程和它管理的Activity是在一个进程里面。
所以,当TabActivity要启动一个activity的时候,会调用到LocalActivityManager的创建activity方法,然后
调用ActivityThread.startActivityNow(),这个方法绕过了ams,就是说ams此时根本不知道
LocalActivityManager已经在暗渡陈仓的启动了一个activity(所以ams的task列表里面没有新启动activity的记
录,所以用户按back键就直接退出我们的应用)。
然后和正常启动activity一样,初始化activity,在初始化activity的时候,有个方法非常重要: activity.attch()
final void attach(...){
....
mWindow.setCallback(this);  
.....
}
mWindow.setCallback(this); 非常重要,它设置window的回调接口,这是我们activity能够接受到key事件的关键所在! 因为在DecorView在接受到事件的时候,会回调这个接口。
如: final Callback cb = getCallback();
                final boolean handled = cb != null && mFeatureId < 0 ? cb.dispatchKeyEvent(event)
                        : super.dispatchKeyEvent(event);

当我们启动FirstActivity的时候,我们设置FirstActivity为PhoneWindow的回调实现,所以,按back键的时候,调用的是FirstActivity的onKeyDown方法。

(四)TabActivity的现状
上面第二点也说了,TabActivity只是个怪胎而已。所以,在后面的发展中肯定会被代替。果然,google在android3.0推出了Fragment这个东东,这个东东就可以代替TabActivity.
不可避免的,和TabActivity相关的类都被声明为Deprecated,包括它的父类ActivityGroup, 已经我们的小雷音寺LocalActivityManager ....
写到这里,不仅有种英雄暮路,美人辞暮的感觉,突然想起了最近热播的楚汉传奇,楚霸王威武一世,到最后,也不免自刎于乌江.. TabActivity曾经在Android2.2/2.3版本时那么显赫一时,终难免被人抛弃。。不仅悲从心来,长歌当哭..

Android TabActivity之感叹的更多相关文章

  1. Android TabActivity中onKeyDown无效问题

    @Override     public boolean onKeyDown(int keyCode, KeyEvent event)     {                  //按下键盘上返回 ...

  2. android TabActivity的局限性 是否还有存在的必要性

     TabActivity的局限性 是否还有存在的必要性 其实谷歌有此举动,我们也应该早就想到了,为什么会这么说呢?那就要从TabActivity的原理开始说起了. 做个假定先: 比如我们最外面的Act ...

  3. Android TabActivity与Activity之间的动画跳转(主要Tabhost中跳转出来的动画效果解决)

    首先,要说的是ActivityA到ActivityB的切换这个相对简单,只要overridePendingTransition(In,out). 这里不就说了.但是这里要说名的ActivityA不能T ...

  4. Android UI开发第三十九篇——Tab界面实现汇总及比较

    Tab布局是iOS的经典布局,Android应用中也有大量应用,前面也写过Android中TAb的实现,<Android UI开发第十八篇——ActivityGroup实现tab功能>.这 ...

  5. 使用ActivityGroup来切换Activity和Layout

    前言 在一个主界面中做Activity切换一般都会用TabActivity,使用方便,Activity互相之间相对独立,但是可定制性不强,而且修改起来很麻烦.当然也可以把layout分开,把逻辑代码全 ...

  6. Android之TabActivity的使用

    TabActivity实现多页显示效果 由于手机屏幕有限,所以我们要尽量充分利用屏幕资源.在我们的应用程序中通常有多个Activity,而且会经常切换显示,这样我们就可以用TabActivity来显示 ...

  7. Android Tab -- 使用TabWidget、TabHost、TabActivity来实现

    原文地址:http://blog.csdn.net/crazy1235/article/details/42678877 TabActivity在API13之后被fragment替代了,所以不建议使用 ...

  8. Android(java)学习笔记122:TabActivity使用

    1.首先我们要知道TabActivity是结合TabHost使用的,于是我们自然而然要说明一下TabHost 所谓的TabHost是提供选项卡(Tab页)的窗口视图容器. 此对象包含两个子对象: 一个 ...

  9. Android之对TabActivity的见解,个人觉得不错

    http://www.cnblogs.com/answer1991/archive/2012/05/08/2489844.html answer1991 无法停止我内心的狂热,对未来的执着. Andr ...

随机推荐

  1. EXPDP IMPDP 知识总结

    Data Pump Export ATTACH Default: job currently in the user's schema, if there is only one Purpose(目的 ...

  2. Objective-C 类,函数调用

    // // main.m // L02HelloObjC // // Created by JinXin on 15/11/25. // Copyright © 2015年 JinXin. All r ...

  3. 将对象保存至文件——CArchive

    CArchive允许以一个二进制的形式保存一个对象的复杂网络,也可以再次装载它们,在内存中重新构造,这一过程叫作串行化/序列化(Serialization),简单的说,CArchive与CFile配合 ...

  4. QT实现单个EXE文件

    有时候发布用Qt写的软件是件令人烦恼的事情,明明发布的只是一个简单功能的小软件,非得再附上一堆超大的动态链接库,实在让人觉得汗颜 . 在可执行文件单文件化方面,有多种方法.常用的是编译并使用静态 Qt ...

  5. How to check a not defined variable in javascript

    javascript里怎么检查一个未定义的变量? in JavaScript null is an object. There's another value for things that don' ...

  6. inline-block(行内区块元素)的详解和应用

    说inline-block(行内区块元素)之前,先说下他另外的2个兄弟 display:inline; 内联元素,简单来说就是在同一行显示.他没有高度,给内联元素设置width和height是没效果的 ...

  7. underscorejs-pluck学习

    2.14 pluck 2.14.1 语法: _.pluck(list, key) 2.14.2 说明: pluck方法根据key对list数组中的每个对象进行检索,返回检索成功的属性值,否则返回und ...

  8. Maven 安装记

    java初学者 昨天通m2e插件把maven项目导入eclipse的时候各种bug,看了各家技术博客,决定安装maven好好了解下. 安装maven也是一波三折的,先是看各种安装指导,结果环境变量都没 ...

  9. php中抽象类和接口的特点、区别和选择

    一.特点: 1.抽象类特点 (1) 用 abstract 来修饰一个类,那么这个类就是抽象类:抽象类绝对不能被实例化,即$abc = new 抽象类名();会报错. (2) 用abstract 来修饰 ...

  10. 百度地图api窗口信息自定义

    百度地图加载完后,完全可以用dom方法操作,比较常用的就是点击mark的弹窗,利用jQuery可以很快的创建弹窗,需要注意的就是地图都是异步加载,所以绑定时间要用 jQuery 事件 - delega ...