Activity Review

Activity Review

参考资料

谷歌Activity参考文档

任务与返回栈, 官方文档的描述

Activity启动方式和Flag详解

Activity完全解析

Activity高级篇:Home键与Back键

Activity概述

一个应用通常由多个彼此松散联系的 Activity 组成。 一般会指定应用中的某个 Activity 为“主”Activity,即首次启动应用时呈现给用户的那个 Activity。 而且每个 Activity 均可启动另一个 Activity,以便执行不同的操作。 每次新 Activity 启动时,前一 Activity 便会停止,但系统会在堆栈(“返回栈”)中保留该 Activity。 当新 Activity 启动时,系统会将其推送到返回栈上,并取得用户焦点。 返回栈遵循基本的“后进先出”堆栈机制,因此,当用户完成当前 Activity 并按“返回”按钮时,系统会从堆栈中将其弹出(并销毁),然后恢复前一 Activity。

启动Activity

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

隐式意图

Intent intent = new Intent(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_EMAIL, recipientArray);
startActivity(intent);

Intent 对象的真正价值所在 — 您可以创建一个 Intent 对象,对您想执行的操作进行描述,系统会从其他应用启动相应的 Activity. <参考文档>

表述:
如果您想允许用户发送电子邮件,可以创建上面的实例 Intent

添加到 Intent 中的 EXTRA_EMAIL extra 是一个字符串数组,其中包含应将电子邮件发送到的电子邮件地址。 当电子邮件应用响应此 Intent 时,它会读取 extra 中提供的字符串数组,并将它们放入电子邮件撰写窗体的“收件人”字段。 在这种情况下,电子邮件应用的 Activity 启动,并且当用户完成操作时,您的 Activity 会恢复执行。

Manifest.xml

<activity
    android: name="com.alex33.SecondActivity"
    android: icon="@drawable/cat"
    android: label="第二个Activity">

    <intent-filter>
        <action android:name="com.alex33.JumpToSecondActiviy"/>
        <category android:name="android.intent.category.DEFAULT"/>
    </intent-filter>
</activity>

SecondActivity.java

Intent i = new Intent();
i.setAction("com.alex33.JumpToSecondActivity");
i.addCategory("android.intent.category.DEFAULT");
startActivity(intent);
通过隐式意图可以不报楼类文件的情况下, 调用一个Activity

Activity几种状态

  1. Active(活动 | Active/Runing):当Activity位于栈顶时,它是可见,有焦点的前台Activity,可以用来响应用户的输入。

  2. Paused(暂停 | Paused):一般情况,你的Activity可见但不具有焦点,例如 当前面的Activity是全透明或非透明的Activity时,下面的Activity就位于Paused状态。

  3. Stopped(停止 | Stoped):当一个Activity彻底不可见时,就处于这个状态。此时Activity完全不可见,但在内存中仍旧保留该Activity的状态和成员信息。

  4. Inactive(销毁 | Killed):当一个Activity被杀死时,就变成Inactive。Inactive Activity会从Activity栈中移除,如果重新显示需要重新启动。一般销毁由系统Dalvik控制。

Activity加载模式

在android里,有4种activity的启动模式,分别为:

  1. standard: 标准模式,一调用startActivity()方法就会产生一个新的实例。

  2. singleTop: 来了intent, 每次都创建新的实例,仅一个例外:当栈顶的activity 恰恰就是该activity的实例(即需要创建的实例)时,不再创建新实例。这解决了栈顶复用问题。

  3. singleTask: 来了intent后,检查栈中是否存在该activity的实例,如果存在就把intent发送给它,否则就创建一个新的该activity的实例,放入一个新的task栈的栈底。肯定位于一个task的栈底,而且栈中只能有它一个该activity实例,但允许其他activity加入该栈。解决了在一个task中共享一个activity。

  4. singleInstance: 这个跟singleTask基本上是一样,只有一个区别:在这个模式下的Activity实例所处的task中,只能有这个activity实例,不能有其他的实例。一旦该模式的activity的实例已经存在于某个栈中,任何应用在激活该activity时都会重用该栈中的实例,解决了多个task共享一个activity。
    这些启动模式可以在功能清单文件AndroidManifest.xml中进行设置,中的launchMode属性。

Activity 生命周期

Activity生命周期A
Activity生命周期Org
Activity生命周期Org

Activity跳转时的方法回调

生命周期回调的顺序经过明确定义,当两个 Activity 位于同一进程,并且由一个 Activity 启动另一个 Activity 时,其定义尤其明确。 以下是当 Activity A 启动 Activity B 时一系列操作的发生顺序:

  1. Activity A 的 onPause() 方法执行。
  2. Activity B 的 onCreate()、onStart() 和 onResume() 方法依次执行。(Activity B 现在具有用户焦点。)
  3. 然后,如果 Activity A 在屏幕上不再可见,则其 onStop() 方法执行。

您可以利用这种可预测的生命周期回调顺序管理从一个 Activity 到另一个 Activity 的信息转变。 例如,如果您必须在第一个 Activity 停止时向数据库写入数据,以便下一个 Activity 能够读取该数据,则应在 onPause() 而不是 onStop() 执行期间向数据库写入数据。

Manifest.xml的细节

清单文件中, intent过滤器有MAIN和LAUNCHER, 代表mainActivity的主入口

<intent-filter>  
    <action android:name = "android.intent.action.MAIN" />
    <category android:name = "android.intent.category.LAUNCHER" />  
</intent-filter>

使用Bundle在Activity间传值

Bundle对象有如下方法:

  • putXxx(String key,Xxx data) : 向Bundle中放入int、String等各种类型的数据

  • putSerializable(String key,Serializable data) : 向Bundle中放入可序列化的对象

  • getXxx(String key):取出int、String等各种类型的数据

  • getSerializable(String key):取出可序列化的对象

当然我们还可以直接调用intent对象的putExtra(String key,Xxx data)方法存入数据,但其本质还是创建或使用了Bundle对象进行传值。

startActivityForResult的使用

A-Activity需要在B-Activtiy中执行一些数据操作,跳转至B-Activity后,B-Activity要将执行操作数据的结果返回给A-Activtiy,此时就需要使用 startActivityForResult()来启动B-Activity了。

使用的三个函数:

  • startActivityForResult (Intent intent, Int requestCode)
  • setResut (int resultCode, Intent intent)
  • onActivityResult (int requestCode, int resultCode, Intent intent)

Step1.

在A中跳转的时候不是采用startActivity(intent) 这个方法,而是startActivityForResult(intent, Int requestCode)的形式,requestCode可以是大于等于0的任何值。

startActivityForResult(intent, 0);

Step2.

在A中重写onActivityResult方法,用来接收B回传的数据,因为传回来的resultCode不同而做差别处理。

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    
    switch (resultCode) { //resultCode为回传的标记
        
        case 20:
            Bundle b=data.getExtras(); //data为B中回传的Intent
            String str=b.getString("str1");//str即为回传的值
            break;

        default:
            break;
    }
}

Step3.
在B中采用setResult方法,并且之后要调用finish方法。

Intent intent=new Intent();  
intent.putExtra("str1", str_bookname);  
setResult(20, data);  
finish(); //关闭掉这个Activity 

关于A-B Activity切换, Home键, Back键的机制

任务与返回栈, 官方文档的描述

Activity 和任务的默认行为总结如下:

  • 当 Activity A 启动 Activity B 时,Activity A 将会停止,但系统会保留其状态(例如,滚动位置和已输入表单中的文本)。如果用户在处于 Activity B 时按“返回”按钮,则 Activity A 将恢复其状态,继续执行。

  • 用户通过按“主页”按钮离开任务时,当前 Activity 将停止且其任务会进入后台。 系统将保留任务中每个 Activity 的状态。如果用户稍后通过选择开始任务的启动器图标来恢复任务,则任务将出现在前台并恢复执行堆栈顶部的 Activity。

  • 如果用户按“返回”按钮,则当前 Activity 会从堆栈弹出并被销毁。 堆栈中的前一个 Activity 恢复执行。销毁 Activity 时,系统不会保留该 Activity 的状态。
    即使来自其他任务,Activity 也可以多次实例化。

Home键与Back键对Activity的生命周期影响

  • 如果按下Back键,系统返回到桌面,并依次执行A:onPause -> A:onStop -> A:onDestroy。

  • 如果按下Home键(非长按),系统返回到桌面,并依次执行A:onPause -> A:onStop。

由此可见,Back键和Home键主要区别在于是否会执行onDestroy。

Back键实现Home键效果

@Override
public void onBackPressed() {
    Intent home = new Intent(Intent.ACTION_MAIN);
    home.addCategory(Intent.CATEGORY_HOME);
    startActivity(home);
}

或者

@Override
public void onBackPressed() {
     moveTaskToBack(true);
} 

moveTaskToBack()此方法直接将当前Activity所在的Task移到后台,同时保留activity顺序和状态。

关于finish()

  1. 将此Activity从Activity栈中移除。
  2. 调用了此Activity的onDestroy方法。

关于Activity的一些技巧

锁定为竖屏

<activity android:name="com.alex33.MainActivity"
    android:label="@string/app_name" 
    android:screenOrientation="portrait">
        // 竖屏为portrait,横屏为landscape
</activity>

去除标题

requestWindowFeature(Window.FEATURE_NO_TITLE);

Android清单文件中MimeType的用途

Intent-Filter中的有一个mimeType。它的作用是告诉Android系统本Activity可以处理的文件的类型。如设置为 “text/plain”表示可以处理“.txt”文件。

<intent-filter>

    <actionandroid:name="android.intent.action.VIEW" />

    <categoryandroid:name="android.intent.category.DEFAULT" />

    <data android:mimeType="image/jpeg ">

</intent-filter>

这样就把当前程序注册为可以打开/查看jpeg类型的图片

当在文件管理器里点击任何jpeg文件, 系统都会试图去执行你的程序。

" image/jpeg "这一类型属于标准的MIME Type。

一个简单的隐式跳转并传递值的Demo

UI

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.goldinfo.sendmessage.MainActivity">

    <ListView
        android:id="@+id/ll"
        android:layout_width="match_parent"
        android:layout_height="match_parent"></ListView>
</RelativeLayout>

item

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:text="TextView"
    android:id="@+id/textView"
    android:textColor="#123897"
    />

代码实现

MainActivity

public class MainActivity extends AppCompatActivity {

    private ListView lv;


    private String[] msgs = {"天气太热了!买了个凉席,一睡变电热毯了!遇到个陌生人,相视一笑,变熟了!桌子太烫,麻将刚码好,嘿,居然糊了!",
            "工作是枯燥的,赚钱是辛苦的,理想却是远大的,等咱有了钱,喝豆浆吃油条,想沾白糖沾白糖,豆浆买两碗,喝一碗,倒一碗!",
            "给你点阳光你就灿烂,给你点洪水你就泛滥。破锅自有破锅盖,丑鬼自有丑女爱,只要情深意似海,麻子也能放光彩!",
            "鸟儿,鸟儿,喳喳叫。清风,清风,去烦恼。祝福,祝福要趁早。短信,短信,恰恰好。朋友,朋友,看到短信笑一笑!",
            "武当派,少林派,不如吃个苹果派;日月教,全真教,不如睡个大懒觉;降龙掌,销魂掌,不如养盆仙人掌;总之,你好我好大家好",
            "我的问候,就是那冰激凌,融在你嘴里,甜在你胃里,爽在你心里。愿你把高温击退,把快乐放飞,生活有滋有味,笑容天天都美!",
            "送你西瓜,爽口爽心顶呱呱;送你电扇,吹走烦躁发发汗;送你清凉油,神清气爽争上游;送你清心茶,伴你天天乐开花!",
            "看事业线,你正走在成功路上;看生命线,你定会健康长寿;看感情线,你桃花运正旺。我的祝福三线合一,愿你快乐无比!",
            "送你五万块,一万健康,一万快乐,一万平安,一万好运,一万幸福,一共五万块红砖。嘿嘿,自己建造个美好城堡吧!",
            "好好活,慢慢过,一年更比一年乐;不要攀,不要比,不要自己气自己;少吃盐,多吃醋,少打麻将多散步。愿你:天天闲里忙着乐!"};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        lv = (ListView) findViewById(R.id.ll);

        ArrayAdapter<String> adapter = new ArrayAdapter<String>(getApplicationContext(), R.layout.item, msgs);

        lv.setAdapter(adapter);

        lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

                //去除点击条目的数据
                String content = msgs[position];

                //使用隐式意图 跳转到短信页面
                Intent intent = new Intent();
                intent.setAction("android.intent.action.SEND");
                intent.addCategory("android.intent.category.DEFAULT");
                intent.setType("text/plain");

                //key值需要到android源码中找
                intent.putExtra("sms_body",content);

                //开启Activity
                startActivity(intent);


            }
        });

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

推荐阅读更多精彩内容