Android 开发艺术探索 1

Android 开发艺术探索 1

Activity的生命周期

  • 不要在onPause()中做重量级的操作,因为必须就得Activity的onPause()执行完之后,新Activity的onCreate(),onStart(),onResume()才能执行,执行好了,就Activity的onStop()才执行,onStop()中也不应做太耗时的操作

  • Activity被杀死之后会调用 onPause, onSaveInstanceState, onStop, onDestroy方法,onSaveInstanceState在onStop之前,有可能在onPause之前,也有可能在onPause之后(个人实验下来基本上都是全部是在onPause之后,况且onSaveInstanceState是和onRestoreInstanceState相对应的,onRestoreInstanceState调用在onStart之后onResume之前,那按理onSaveInstanceState也应该在onPause之后)。只要onSaveInstanceState方法调用了,不管你有没有对Bundle写入数据,它都会将Bundle发送出去,即使Bundle不携带信息

  • Activity被重新创建后,系统会调用onRestoreInstanceState方法,并把之前在onSaveInstanceState中保存的Bundle对象同时传给onCreate方法和onRestoreInstanceState方法,onRestoreInstanceState调用在onStart之后onResume之前。这两个的区别使用onCreate恢复数据时需要判断Bundle是否为空(因为正常启动时Bundle为空),而onRestoreInstanceState则不用判断,只要这个方法被调用,Bundle是一定有值的

  • 在onSaveInstanceState和onRestoreInstanceState方法中,系统会自动帮我们做一些当前Activity(有id)视图结构的保存、恢复工作。工作流程大致是这样的:每个View也有onSaveInstanceState和onRestoreInstanceState方法,当Activity被意外结束时,Activity会调用onSaveInstanceState去保存数据,随后Activity会委托Window去保存数据,Window再委托它上面的顶层容器去保存数据,顶层容器是一个ViewGroup,一般很可能是DecorView,顶层容器再去一一通知它的子元素保存数据。这是一种典型的委托思想,View的绘制过程、事件分发都是采用类似的思想。

  • onSaveInstanceState在Activity正常销毁时不会调用,但是当按Home键或者启动新的Activity时,会单触发onSaveInstanceState的调用

  • 资源相关的系统配置发生改变会导致Activity被杀死并重新创建。通过对android:configChanges进行设定,指定当这些系统配置发生变化时,Activity不被杀死。当指定属性发生变化时,系统不会调用onSaveInstanceState和onRestoreInstanceState来存储或恢复数据,取而代之调用onConfigurationChanged方法
    <activity android:name=".MainActivity" android:configChanges="locale|orientation|screenSize|keyboardHidden">
    实验后表明,即使指定了相关属性,屏幕还是可以旋转,Activity也会跟着旋转,但是Activity不会注销并重新启动

Activity的启动模式

  • standard 标准模式 系统默认为此模式,每次启动一个Activity会重新创建一个新的实例,而不去管这个实例是否已经存在,多次启动同一个Activity,系统会创建多个实例。standard模式下,谁启动了这个Activity,这个Activity就运行在启动它的那个Activity所在的栈中(经个人实试TaskAffinity对standard模式下Activity有效,但优先程度没有谁启动去谁那儿高。只有在程序的入口或者与带有Flag的Intent配合时才有效)。所以如果在程序中用ApplicationContext去启动standard模式的Activity会报错,因为ApplicationContext非Activity类型,没有任务栈

  • singleTop 栈顶复用模式 这种模式下,如果新Activity已经位于任务栈的栈顶,那么这个Activity不会被重新创建,栈顶Activity的onNewIntent方法会被调用

  • singleTask 栈内复用模式 这种模式下,只要Activity在目标栈中存在,则多次启动此Activity都不会重新创建实例,而会调用onNewIntent方法
    将singleTask和TaskAffinity分开来讲的都是耍流氓啊!TaskAffinity用来指定Activity启动时想去的任务栈,如果没有指定,则默认的TaskAffinity为当前应用的包名,TaskAffinity属性主要和singleTask或者allowTaskReparenting配对使用,其他情况没有意义。TaskAffinity的值必须为字符串,且必须带有"."
    具有singleTask模式的Activity A请求启动后,系统首先寻找A的目标栈是否存在,如果不存在,则创建目标栈,创建A的实例放入栈中;如果目标栈存在,同时里面不存在A的实例,则创建A的实例并放入栈中;如果目标栈存在,且里面已经有A的实例存在了,则系统直接将A的实例调到栈顶(A实例的上面全部出栈),并调用它的onNewIntent方法

  • singleInstance 单实例模式,这种模式下,系统会为Activity单独创建一个独立的任务栈,这个任务栈中只能有这个Activity的实例存在

  • TaskAffinity与allowTaskReparenting配合使用,如果程序A启动了程序B的Activity C,并且C的allowTaskReparenting设为ture,则C会在A的任务栈里面,但是当B应用启动之后,B会创造原本C想要的那个任务栈(默认的包名呗),那么系统就会直接将C从A的任务栈转移到B的任务栈,所以B应用启动之后不是B的入口Activity,而是C

  • 尽管singleTask和SingleTop模式的Activity有时系统不会为其创建新的实例,而是调用onNewIntent方法,但是Activity的onPause和onResume方法还是会调用的。调用循序依次为onPause,onNewIntent,onResume

  • 除了通过launchMode来设置启动模式,还可以通过在intent中addFlags来设置,且通过Intent的优先级高于manifest
    Intent intent = new Intent(DActivity.this,AActivity.class);
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    startActivity(intent);

  • Activity几种常用的Flags
    FLAG_ACTIVITY_NEW_TASK//指定为singleTask模式启动
    FLAG_ACTIVITY_SINGLE_TOP//指定为singleTop模式启动
    FLAG_ACTIVITY_CLEAR_TOP//?
    FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS//不出现在历史列表中,等同于android:excludeFromRecents="true"

IntentFilter的匹配规则

  • Intent分两种,显示Intent和隐式Intent,如果同时存在,显示Intent的优先级高于隐式Intent。为了匹配隐式Intent,需要同时匹配intent-filter中的action,category,data信息才算匹配成功。如果一个Activity有多个intent-filter,那么一个Intent只要能够匹配任意一组intent-filter即可启动Activity

  • action的匹配规则:一个intent-filter中可以有多个action,Intent中的action只要与其中任意一个action相同即可匹配成功

  • category的匹配规则:Intent中可以没有category,但是如果一旦有category,不管有几个,每个都要能够与intent-filter中的任意一个category相同。不过在调用startActivity或startActivityForResult方法时,系统会默认为Intent加上DEFAULT这条category,所以为了能够接受隐式调用,intent-filter中也要加上DEFAULT这一条

  • data的匹配规则:一个intent-filter中可以有多个data,Intent中的data数据必须其中任意一条匹配才能匹配成功

  • data的语法:data由mimeType和URI两部分组成,mimeType指媒体类型,URI结构为 <scheme>://<host>:<port>[<path>|<pathPrefix>|<pathPattern>],在mimiType指定后, android:scheme有可能有默认的值content或file

<data android:scheme="string"
      android:host="string"
      android:port="string"
      android:path="string"//表示完整路径
      android:pathPattern="string"//表示完整路径,可以包含通配符"*",表示0或多个任意字符
      android:pathPrefix="string"//表示路径前缀
      android:mimeType="string" 
/>
  • 如果要为Intent指定完整的data,使用setDataAndType方法,因为setData方法和setType方法会互相清除对方的值

  • 对于Service尽量使用显示调用

  • 使用隐式调用时,可以实现使用PackageManager的resolveActivity方法或者Intent的resolveActivity来检查是否有Activity能够响应我们的隐式调用
    abstract ResolveInfo resolveActivity(Intent intent, int flags)
    flags使用MATCH_DEFAULT_ONLY,因为category不含default的是不能响应隐式调用的

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

推荐阅读更多精彩内容