Android——Activity学习(下)

学习资料:

本篇是个挖坑之作,步子跨得太大扯着了。不知天高地厚地开始学习后,发现涉及到很多暂时无法理解的东西。遂,中道崩殂,哈哈:),估计明年这个时候才能补充了

Android——Activity学习(上)学习了Activity的生命周期,启动模式,任务栈,本篇进行学习工作过程

对于用户来说,一个APP能够感知的就是一个Activity,四大组件的其他三位,都是在后台运行的,用户是看不到的,不可感知的。根据上篇的学习,Activity有不同的启动模式,启动方式也可以分为显示Intent隐式Intentfinish()方法可以结束一个组件的运行。


1. 工作过程 <p>

在一个现有Activity_A中,经常会使用一个Intent来开启一个Activity_B

Intent intent = new Intent(Activity_A.this,Activity_B.class);
startActivity(intent);

startActivity()方法可以作为学习的入口点

扫了一眼Activity源码的行数,加上注释7177行,相对于View的23000行来说,小巫见大巫。最近一段时间的学习,感觉最明显的变化便是看源码时的心态。然而也仅仅是心态有了点朝好的趋势发展,阅读代码的能力还是渣


1.1 startActivity() 开启Activity<p>

有两种重载重载方式,startActivity(Intent intent)内部调用了startActivity(Intent intent, @Nullable Bundle options)

@Override
public void startActivity(Intent intent, @Nullable Bundle options) {
    if (options != null) {
            startActivityForResult(intent, -1, options);
    } else {//兼容重载方法
            // Note we want to go through this call for compatibility with
            // applications that may have overridden the method.
            startActivityForResult(intent, -1);
    }
}

最终两种形式的startActivity()方法都会调用startActivityForResult()方法

Activity_A并不知道Activity_B的存在,但Activity_A通过使用Intent来启动Activity_B,显式是通过指定类对象,隐式则更加显得强大,通过在AndroidManifest.xml清单文件中使用的action指定的Activity_B的名字来启动。这个设计使Activity耦合性很松散,模块化程度更高,之后维护和升级也更加方便些。


1.2 startActivityForResult()带有返回结果的开启Activity <p>

方法源码:

public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,@Nullable Bundle options) {
    if (mParent == null) {//mParent是ActvityGroup,API13后废弃,推荐由Framgment代替
        Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity(this, mMainThread.getApplicationThread(), mToken, this,
                    intent, requestCode, options);
        if (ar != null) {
            mMainThread.sendActivityResult(mToken, mEmbeddedID, requestCode, ar.getResultCode(),
            ar.getResultData());
        }
        if (requestCode >= 0) {//当前Activity返回一个result,无论它发生了什么
            mStartedActivity = true;
        }
        cancelInputsAndStartExitTransition(options);
        // TODO Consider clearing/flushing other event sources and events for child windows.
    } else {//mParent不为null
        if (options != null) {
            mParent.startActivityFromChild(this, intent, requestCode, options);
        } else {兼容重载方法,以确保重载方法可以使用
            mParent.startActivityFromChild(this, intent, requestCode);
        }
    }
}

上面的代码需要重点关注mParent==null部分内的的逻辑,mParent是一个ActivityGroup,只是在API13之后,被废弃,系统推荐另外一个坑,Frrgment来替代。

mInstrumentationActivity类中的一个成员变量,Instrumentation可以看作是APP和系统之间的监控器,用来监控应用程序和系统间的交互

mMainThread类型是ActivityThread,这里代表的就是程序的主线程。mMainThread.getApplicationThread()获得是一个ActivityThread的内部类ApplicationThread对象。在Android应用程序中,每一个进程就用一个ActivityThread实例对象来表示

本篇博客学习挖的1号坑——ActivityThread,暂时不理解它的工作过程


1.3 Instrumentation的execStartActivity()方法 <p>

源码:

public ActivityResult execStartActivity(Context who, IBinder contextThread, IBinder token, Activity target, Intent intent, int requestCode) {  
        IApplicationThread whoThread = (IApplicationThread) contextThread;  
        if (mActivityMonitors != null) {...}  
        try {  
            int result = ActivityManagerNative.getDefault() 
                .startActivity(whoThread,intent,intent.resolveTypeIfNeeded(who.getContentResolver()), null, 0, token, target != null ? target.mEmbeddedID : null, requestCode, false, false);  //才真正开始开启Activity
           checkStartActivityResult(result, intent);//检查异常
        } catch (RemoteException e) {  
        }  
    return null;  
}

整个方法内关键之处在于ActivityManagerNative.getDefault().startActivity(...),真正启动一个Activity便是这行代码。

ActivityManagerNative.getDefault()返回的结果是一个IActivityManager,是一个接口。ActivityManagerNative(AMN)ActivityManagerService(AMS)的父类,AMN继承之Binder并实现了IActivityManager这个Binder接口,因此AMS也是一个Binder,它是IAcitityManager的具体实现。由于ActivityManagerNative.getDefault()结果其实是一个IActivityManager类型的Binder对象,最终的具体实现是AMS,所以Activity的启动也就转移到了AMS中的startActivity()方法。

checkStartActivityResult(result,intent)用于检查启动Activity的结果,当无法正常开启一个Activity时,就会抛出一个异常。例如,一个Activity没有在AnroidManifest.xml中注册时,便会抛出:

Unable to find explict activity class ;
have you declared this activity in your AndroidManifest.xml ?

2号大坑——Binder,任教主推荐了两篇,Android深入浅出之Binder机制Android Bander设计与实现 - 设计篇 ,一脸懵逼,属于有生年看懂系列

接下来看AMSstartActivity()方法


1.4 AMS的startActivity()方法

源码:

卒...

感觉再看下去属于浪费时间,再储备点知识后,再来学习


2. 最后 <p>

尺度太大,学不动,先放弃,这次学习没把握好尺度

写博客以来,第一次中途放弃,实在没有啥效率

2016.10.14 16:28

共勉 :)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容