Activity之Intent、生命周期、启动模式

1.Activity的理解

  • Activity 直译为活动,它是Android定义的四大应用组件之一,也是最重要用的最多的
  • Activity用来提供一个能让用户操作并与之交互的界面
  • 一个应用有多个界面,也就是包含多个Activity(还存在单Activity+多Fragment 的)
  • 打电话、发短信、拍照、发邮件等功能都是通过Activity来做的

2.Intent的理解

  • Intent 直译为意图,也就是你想要做什么或想去哪
  • Intent是ActivityServiceBroadcastRecevier这个三个应用组件之间通信的信使
  • 例如: 我要在Activity中启动另一个Actvity, 就必须使用Intent对象

  • 意图对象还可以携带数据
  • 注意: Intent不是Android中的四大应用组件之一
  • Intent的分类:显式意图 : 明确指定的目标组件的意图 创建对象 : Intent(Context context, Class clazz) 何时使用 : 当操作当前自己应用的组件时使用。
                          隐式意图 : 没有明确指定目标组件的意图 创建对象 : Intent(String action) 何时使用 : 当操作其它应用的组件时使用。

        注:在Intent内部维护了一个HashMap<String,Objec>

2.1 IntentFilter的理解

      隐式调用需要Intent能够匹配目标组件的IntentFilter中所设置的过滤信息,匹配不到则无法启动 目标Activity,IntentFilter中过滤信息有action、category、data.

  • 在配置Activity时, 可以为Activity指定一个IntentFilter的配置
  • 如果你的Activity希望其它应用能访问到, 需要配置<intent-filter>
  • 如果你想启动其它应用的界面你必须用隐式intent, 且目标界面Activty配置了<intent-filter>
  • 它的作用类似于web中的为Servlet配置的<url-pattern>

2.2 Intent的七大属性(ComponentName、Action、Category、Data、Type、Extra、Flag

Intent七大属性是指Intent的ComponentName、Action、Category、Data、Type、Extra、Flag,七个属性,总体上可以分为3类:

第一类:启动,有ComponentName(显式),Action(隐式),Category(隐式)。

第二类:传值,有Data(隐式),Type(隐式),Extra(隐式、显式)。

第三类:启动模式,有Flag。

  • ComponentName: 用于指出启动的组件(实现页面的跳转)
intent = new Intent();
intent.setComponent(new ComponentName(this, SecondActivity.class));
startActivity(intent);
  • Action:Action属性的值为一个字符串,它代表了系统中已经定义了一系列常用的动作。通过setAction()方法或在清单文件AndroidManifest.xml中设置。默认为:DEFAULT。
          Action、Category属性与intent-filter配置:通常,Action、Category属性结合使用,定义这两个属性都是在配置文件的<intent-filter>节点中。Intent通过定义Action属性(其实就是一段自定义的字符串),这样就可以把Intent与具体的某个Activity分离,实现了解耦。否则,每次跳转,都要写成类似new Intent(MainActivity.this,NextActivity.class)这样的形式,也就是说必须将要跳转的目标Activity的名字写出来,这样的编码其实是“硬编码”,并没有实现松耦合。调用Intent对象的setAction()方法实现页面跳转虽然略微复杂(需要在AndroidManifest.xml文件中配置)
    1、示例代码:
    Intent intent = new Intent(); 
    intent.setAction("com.train.task01.editactivity"); 
    startActivity(intent);
    //在配置文件中注册Activity的时候需要声明:
    <activity android:name="com.train.taskstack01.EditActivity">
      <intent-filter>
          <action android:name="com.train.task01.editactivity" />
          <category android:name="android.intent.category.DEFAULT" />   
      </intent-filter>
    </activity>
    //当某个页面是默认启动页面时,需要定义Action、Category的属性必须为以下字符串:【设置任务入口】
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
    
    
    常用的属性
    ACTION_MAIN:(android.intent.action.MAIN)Android程序入口,每个Android应用必须且只能包含一个此类型的Action声明。 
    ACTION_VIEW: (android.intent.action.VIEW) 显示指定数据。
    ACTION_EDIT: (android.intent.action.EDIT) 编辑指定数据。 
    ACTION_DIAL: (android.intent.action.DIAL) 显示拨号面板。
    ACTION_CALL: (android.intent.action.CALL) 直接呼叫Data中所带的号码。  
    ACTION_ANSWER: (android.intent.action.ANSWER) 接听来电。  
    ACTION_SEND: (android.intent.action.SEND) 向其他人发送数据(例如:彩信/email)。  
    ACTION_SENDTO:  (android.intent.action.SENDTO) 向其他人发送短信。
    ACTION_SEARCH: (android.intent.action.SEARCH) 执行搜索。  
    ACTION_GET_CONTENT: (android.intent.action.GET_CONTENT) 让用户选择数据,并返回所选数据
    ACTION_BOOT_COMPLETED:Android系统在启动完毕后发出带有此Action的广播(Broadcast)。 
    ACTION_TIME_CHANGED:Android系统的时间发生改变后发出带有此Action的广播(Broadcast)。 
    ACTION_PACKAGE_ADDED:Android系统安装了新的Application之后发出带有此Action的广播(Broadcast)。 
    ACTION_PACKAGE_CHANGED:Android系统中已存在的Application发生改变之后(如应用更新操作)发出带有此Action的广播(Broadcast)。 
    ACTION_PACKAGE_REMOVED:卸载了Android系统已存在的Application之后发出带有此Action的广播(Broadcast)。  

    Category:Category属性用于指定当前动作(Action)被执行的环境。通过addCategory()方法或在清单文件AndroidManifest.xml中设置。默认为:CATEGORY_DEFAULT。
    Intent intent = new Intent(); 
    intent.setAction(Intent.ACTION_MAIN); 
    intent.addCategory(Intent.CATEGORY_HOME); 
    startActivity(intent); 
    
    常用属性
    CATEGORY_DEFAULT: (android.intent.category.DEFAULT) Android系统中默认的执行方式,按照普通Activity的执行方式执行。 
    CATEGORY_HOME: (android.intent.category.HOME) 设置该组件为Home Activity。
    CATEGORY_PREFERENCE: (android.intent.category.PREFERENCE) 设置该组件为Preference。 
    CATEGORY_LAUNCHER: (android.intent.category.LAUNCHER) 设置该组件为在当前应用程序启动器中优先级最高的Activity,通常与入口ACTION_MAIN配合使用。
    CATEGORY_BROWSABLE: (android.intent.category.BROWSABLE) 设置该组件可以使用浏览器启动。
    CATEGORY_BROWSABLE:设置该组件可以使用浏览器启动。 
    CATEGORY_GADGET:设置该组件可以内嵌到另外的Activity中。

  • Data:Data通常是URI格式定义的操作数据。例如:tel:// 。通过setData()方法设置。
    在intent-filter中指定data属性的实际目的是:要求接收的Intent中的data必须符合intent-filter中指定的data属性,这样达到反向限定Intent的作用
    			// 打开网页
    			intent = new Intent(Intent.ACTION_VIEW);
    			intent.setData(Uri.parse("http://www.baidu.com"));
    			startActivity(intent);
    			// 打电话
    			intent = new Intent(Intent.ACTION_VIEW);
    			intent.setData(Uri.parse("tel:183****8515"));
    			startActivity(intent);
            
                常用属性
                tel://:号码数据格式,后跟电话号码。 
                mailto://:邮件数据格式,后跟邮件收件人地址。
                smsto://:短息数据格式,后跟短信接收号码。  
                content://:内容数据格式,后跟需要读取的内容。  
                file://:文件数据格式,后跟文件路径。  
                market://search?q=pname:pkgname:市场数据格式,在Google Market里搜索包名为pkgname的应用。  
                geo://latitude, longitude:经纬数据格式,在地图上显示经纬度所指定的位置。

  • Extras:Extras属性主要用于传递目标组件所需要的额外的数据。通过putExtras()方法设置。Extra可以传递基本类型,String类型以及实现了Serializable或者Parcelable接口的类。
    通过intent.putExtra(键, 值)的形式在多个Activity之间进行数据交换

    常用属性
    EXTRA_BCC:存放邮件密送人地址的字符串数组。 
    EXTRA_CC:存放邮件抄送人地址的字符串数组。
    EXTRA_EMAIL:存放邮件地址的字符串数组。 
    EXTRA_SUBJECT:存放邮件主题字符串。 
    EXTRA_TEXT:存放邮件内容。 
    EXTRA_KEY_EVENT:以KeyEvent对象方式存放触发Intent的按键。  
    EXTRA_PHONE_NUMBER:存放调用ACTION_CALL时的电话号码。 

  • Type:Type是对Data的类型作进一步的说明。Type在manifest中的设置同样也在<data>标签中,是data的mimeType属性。
    mimeType包括许多文件类型,包括图片、视频、音频等等,每种类型下也可以包含多种文件格式,以下举例部分:
     

    text/plain纯文本
    image/gifimage/gif
    image/jpegjpeg图像
    video/mpegMPEG动画
    audio/mp3mp3音乐

    也可以不指定具体文件格式,只指定文件类型:
     

    image/*指定类型为image的所有文件
    audio/*指定类型为audio的所有文件
    video/*

    指定类型为video的所有文件

    播放视频:
    Intent intent = new Intent(); 
    Uri uri = Uri.parse("file:///sdcard/media.mp4"); 
    intent.setAction(Intent.ACTION_VIEW);
    intent.setDataAndType(uri, "video/*"); 
    startActivity(intent);
  • Flags
    FLAG_ACTIVITY_NEW_TASK
    该标记的作用时为Activity 指定“singleTask”启动模式,其效果和在xml中指定该启动模式相同。
    
    FLAG_ACTIVITY_SINGLE_TOP
    该标记的作用时为Activity指定“singleTop”启动模式,其效果和在xml中指定该启动模式相同。
    
    FLAG_ACTIVITY_CLEARP_TOP
    具有此标记位的Activity,当它启动时,在同一个任务栈中所有位于它上面的Acivity都要出栈。这个标记位一般会和singleTask启动模式一起出现,在这种情况下,被启动Activity的实例已经存在,那么系统就会调用它的onNewIntent。如果被启动的Activity采用standard模式启动,那么它连同它以上的Activity都要出栈,系统会创建新的Activity实例并放入栈顶。
    
    FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
    具有这个标记位的Activity不会出现在历史Activity的列表中,当某些情况下我们不希望用户通过历史列表回到我们的Activity的时候这个标记比较有用。它等同于在XML中指定Activity的属性android:excludeFromRecents="true"。
    
    

3.Activity的生命周期

  • 运行状态:可见也可操作
  • 暂停状态:可见但不可操作
  • 停止状态:不可见,但对象存在
  • 死亡状态:对象不存在

onCreate:在首次创建 Activity 时调用。系统向此方法传递一个 Bundle 对象,其中包含 Activity 的上一状态,不过前提是捕获了该状态,而后会调用onStart方法。(可以在此方法中执行所有正常的静态设置 ,比如:创建视图、将数据绑定到列表等等。)
onStart:在 Activity 即将对用户可见之前调用。而后如果Activity转入了前台就会调用onResume方法。 如果此时直接屏幕熄灭或者用户按下home键则会直接调用onStop方法,当然这种情况比较极端。
onResume:在 Activity 即将开始与用户进行交互之前调用。 此时,Activity 处于 Activity 堆栈的顶层,并具有用户输入焦点。当跳转另一个Activity,或者退出当前Activity后会调用onPause方法。
onPause:在系统即将开始继续另一个 Activity 时调用。 此方法通常用于确认对持久性数据的未保存更改、停止动画以及其他可能消耗 CPU 的内容,诸如此类。 它应该非常迅速地执行所需操作,因为它返回后,下一个 Activity 才能继续执行,所以不能执行耗时操作。而后正常情况下会调用onStop方法。但是有一种极端情况,就是如果这个时候快速让 当前Activity 返回前台,则会调用onResume方法。
onStop:在 Activity 对用户不再可见时调用。如果 Activity 被销毁,或另一个 Activity(一个现有 Activity 或新 Activity)继续执行并将其覆盖,就会调用此方法。而后如果 Activity 恢复与用户的交互,则会调用 onRestart 方法,如果 Activity 被销毁,则会调用onDestroy方法。
onRestart:在Activity被停止后再次启动时调用(即屏幕熄灭后再次回到app,按下home键后再次回到app),而后会调用onStart方法。
onDestroy:在 Activity 被销毁前调用,这是 Activity 收到的最后调用。 当 Activity 结束(对 Activity 调用了 finish 方法),或系统为节省空间而暂时销毁该 Activity 实例时,可能会调用它。 你可以通过 isFinishing 方法区分这两种情形

Activity于Fragment 周明周期

onAttach():当Activity和Fragment交互的时候,我们可以在Activity中通过 Fragment.setArguments()的方法为Fragment提供数据,然后再Fragment的onAttach()方法中 getArguments()获得一个Bundle对象。

onCreateView():创建该Fragment对应的视图,在这里你必须将创建的视图返回诶调用者。它跟onCreate()的区别:onCreate()是指创建该Fragment,你可以在其中初始化除了View之外的东西。

onActivityCreated()

当Activity的onCreate()方法调用时,该方法被调用

onDetach()

当Fragment和Activity解除关联时调用该方法。

onActivityCreated()

当Activity中的onCreate方法执行完后调用。   

问题一:从A-Activity跳转到B-Activity生命周期是?

A_onCreate-->A_onStart-->A_onResume-->A_onPause-->B_onCreate-->B_onStart-->B_onResume-->A_onStop

问题二:从A-Activity跳转到B-Activity,然后再按Home的生命周期是?

A_onCreate-->A_onStart-->A_onResume-->A_onPause-->B_onCreate-->B_onStart-->B_onResume-->A_onStop-->B_onPause-->B_onStop

问题三:从A-Activity跳转到B-Activity,再返回到A-Activity

A_onCreate-->A_onStart-->A_onResume-->A_onPause-->B_onCreate-->B_onStart-->B_onResume-->A_onStop-->B_onPause-->A_onRestart--->A_onstart--->A_onResume-->B_onStop--->B_onDestroy

lauchMode 启动模式

1. standard  默认标准的启动模式,每次startActivity都是创建一个新的activity的实例。

              应用场景: 适用于绝大大数情况

2. singleTop  单一顶部,如果要开启的activity在任务栈的顶部已经存在,就不会创建新的实例,

              而是调用 onNewIntent() 方法。

              应用场景: 浏览器的书签。 避免栈顶的activity被重复的创建,解决用户体验问题。

              例如,某个新闻客户端的新闻内容页面,如果收到10个新闻推送,每次都打开一个新闻内容页面是很烦人的。

3. singleTask 单一任务栈 , activity只会在任务栈里面存在一个实例。如果要激活的activity,在任务栈里面已经存在,就不会创建新的activity,而是复用这个已经存在的activity,调用 onNewIntent() 方法,并且清空这个activity任务栈上面所有的activity

              应用场景:浏览器的书签, 整个任务栈只有一个实例,节约内存和cpu的目的

              注意: activity还是运行在当前应用程序的任务栈里面的。不会创建新的任务栈。

4. singleInstance  单态 单例模式

              单一实例,整个手机操作系统里面只有一个实例存在。不同的应用去打开这个activity 共享公用的同一个activity。

              他会运行在自己单独,独立的任务栈里面,并且任务栈里面只有他一个实例存在。

              应用场景:呼叫来电界面 InCallScreen、手机联系人界面 闹钟

了解更多

Intent 能传递多大 Size 的数据?(附阿里答案)

Activity面试你所需知道的一切

2019 Android 高级面试题总结

Activity生命周期
Activity 的 36 个问题,你还记得几个?

5 道刁钻的 Activity 生命周期面试题

每日一道面试题(第4期)---launchMode的应用场景

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
在使用 `new Intent()` 创建 Intent 对象时,可以通过设置启动模式来指定如何启动Intent 所代表的组件(Activity 或 Service)。启动模式可以在 `Intent` 构造方法中设置,也可以通过 `Intent` 的 `setFlags()` 方法设置。 常用的启动模式包括: 1. `FLAG_ACTIVITY_NEW_TASK`: 如果启动的组件不在当前任务(Task)中,那么会在新的任务中启动该组件。 2. `FLAG_ACTIVITY_CLEAR_TOP`: 如果要启动的组件已经在任务栈中存在,那么会将该组件之上的所有活动都关闭,并重新打开该组件。 3. `FLAG_ACTIVITY_SINGLE_TOP`: 如果要启动的组件已经在栈顶,那么不会重新创建该组件,而是调用其 `onNewIntent()` 方法进行更新。 4. `FLAG_ACTIVITY_NO_HISTORY`: 如果启动的组件在退出后立即销毁,那么不会将其加入到任务栈中。 5. `FLAG_ACTIVITY_CLEAR_TASK`: 如果启动的组件已经在任务栈中存在,那么会将该组件之上的所有活动都关闭,并销毁该任务栈。 例如,可以使用以下代码创建一个在新的任务中启动Intent 对象: ```java Intent intent = new Intent(this, MainActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent); ``` 这个示例代码使用 `FLAG_ACTIVITY_NEW_TASK` 启动一个新的任务,并在其中启动 `MainActivity` 组件。 需要注意的是,启动模式会影响组件的启动方式和生命周期,需要根据具体情况进行设置和调整,避免出现不必要的错误和问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值