Activity的基础知识(下)

上篇总结了Activity的一些知识,现在继续对Activity的知识进行梳理,包括Activity直接传递数据,Activity的生命周期,Activity的启动模式等.
1.intent传递数据:
使用startActivity方法,intent的putExtra()方法,以键值对的形式传递数据,该方法有很多重载方法,可以根据传递数据的不同类型选择合适的方法.除了有putExtra()方法外,还有putExtras()方法,传递的参数是Bundle.

      //putExtra()方法携带数据
      Intent starter = new Intent(context, ActivityA.class);
      starter.putExtra("key", "value");
     // 对应取出数据方法
      String key = getIntent().getStringExtra("key");
      //intent携带Bundle封装数据
        Intent starter = new Intent(context, ActivityA.class);
        Bundle bundle = new Bundle();
        bundle.putString("key","value");
        starter.putExtras(bundle);
      //intent取出Bundle携带的数据
       Bundle bundle = getIntent().getExtras();
        String key = bundle.getString("key");

如果传递的是对象,这个对象要实现序列化,也就是实现Parcelable或者Serializable接口.
如果希望被启动的页面返回数据,需要使用startActivityForResult()方法,这个方法中需要设置访问号,用来区分不同的访问者.并且在启动页重写onActivityResult方法用来接收返回的数据,

//mainActivity中点击button跳转activity
  mButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(MainActivity.this, " add ", Toast.LENGTH_SHORT).show();
                Intent intent = new Intent(MainActivity.this, ActivityA.class);
                startActivityForResult(intent, 1);

            }
        });
//被启动的Activity中点击back键的时候回传数据
 @Override
    public void onBackPressed() {
        Log.d(TAG, "onBackPressed: ");
        Intent intent = new Intent();
        intent.putExtra("activityA", "back");
        setResult(RESULT_OK, intent);
        super.onBackPressed();
    }

//接收数据
@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        Log.d(TAG, "onActivityResult: " + " requestCode" + requestCode + " result " + resultCode);
        switch (requestCode) {
            case 1:
                if (resultCode == RESULT_OK) {
                    Toast.makeText(this, data.getStringExtra("activityA"), Toast.LENGTH_SHORT).show();
                }
                break;
            default:

                break;
        }
    }

2.两种情况下的Activity的生命周期.
正常情况下的生命周期,正常情况是指用户的正常操作下的Activity的生命周期.后面会分析异常情况下的生命周期.
onCreate: Activity第一次创建时候的回调,主要是在这个方法进行初始化工作,比如初始化控件和事件绑定工作.
onStart:Activity从不可见状态变成可见状态.
onResume:Activity变成前台,可以和用户交互.
onPause:Activity可见但是不能和用户交互.
onStop:Activity从可见变得不可见,成为后台Activity.
onDestroy:Activity销毁时调用.
onRestart:Activity从后台变成前台Activity.
在启动Activity和两个Activity之间跳转时,可以知道Activity的生命周期变化过程,有两个说明:(1)在两个Activity跳转时,第一个Activty的onPause,onStop方法和第二个Activity的生命周期方法调用时机.

10-15 07:56:04.128  4170  4170 D MainActivity_life: onPause: 
10-15 07:56:04.249  4170  4170 D ActivityA_life: onCreate: 
10-15 07:56:04.259  4170  4170 D ActivityA_life: onStart: 
10-15 07:56:04.265  4170  4170 D ActivityA_life: onResume: 
10-15 07:56:05.053  4170  4170 D MainActivity_life: onStop: 

第一个Activity先执行onPause方法,第二个Activity才能创建.这也就意味着在onPause方法中不能执行太耗时的操作,否则会影响第二个Activity的创建.在源码(ActivityStack)中有这样的注释:

 // We need to start pausing the current activity so the top one can be resumed...

(2)onStart和onResume,onPause和onStop这两对方法的实质不同处:onStart和onStop这两个方法是从Activity的可见性来区分的,onResume和onPause是从Activity是否处于前台,是否可以和用户交互来区分的,注意在onPause调用时Activity还是可见的,调用时机比如弹出dialog时,下面的Activity是可见的.这个时候调用的是onPause方法.
异常情况下Activity的生命周期:异常情况下是指资源相关配置发生变化或后台Activity被系统回收时Activity的生命周期.后台Activity被系统回收的情况比较难复现,在资源相关配置发生变化时和后台Activity被回收时的生命周期执行过程是一样的,比较容易复现的就是横竖屏切换时的生命周期执行过程.在 AndroidManifest的Activity组件下配置android:screenOrientation标签,当设置可以横竖方向随着方向感应器来调节时,在切换时会出现先销毁Activity再创建的过程.
过程:

10-15 08:45:47.979  4170  4170 D MainActivity_life: onCreate: 
10-15 08:45:48.045  4170  4170 D MainActivity_life: onStart: 
10-15 08:45:48.048  4170  4170 D MainActivity_life: onResume: //创建过程
//开始切换到横屏 activity先销毁 再创建
10-15 08:45:51.278  4170  4170 D MainActivity_life: onPause: 
10-15 08:45:51.280  4170  4170 D MainActivity_life: onStop: 
10-15 08:45:51.281  4170  4170 D MainActivity_life: onDestroy: 
10-15 08:45:51.325  4170  4170 D MainActivity_life: onCreate: 
10-15 08:45:51.382  4170  4170 D MainActivity_life: onStart: 
10-15 08:45:51.389  4170  4170 D MainActivity_life: onResume: 

在这种情况下有可能会有数据的丢失,系统提供用来保存数据和还原数据的方法:onSaveInstanceState和onRestoreInstanceState.用方法参数Bundle可以保存和还原数据.

10-15 08:54:13.146  4649  4649 D MainActivity_life: onPause: 
10-15 08:54:13.146  4649  4649 D MainActivity_life: onSaveInstanceState: 
10-15 08:54:13.149  4649  4649 D MainActivity_life: onStop: 
10-15 08:54:13.149  4649  4649 D MainActivity_life: onDestroy: 
10-15 08:54:13.175  4649  4649 D MainActivity_life: onCreate: 
10-15 08:54:13.255  4649  4649 D MainActivity_life: onStart: 
10-15 08:54:13.256  4649  4649 D MainActivity_life: onRestoreInstanceState: 
10-15 08:54:13.264  4649  4649 D MainActivity_life: onResume:

可以根据需要设置android:screenOrientation标签,设定activity的方向,如果activity的方向是需要横竖屏切换,但是不容许销毁Activity,可以设置如下标签,当这些情况(常用的)发生变化是不会重新走Activity的生命周期方法,只会调用onConfigurationChanged,可以根据情况在这个方法里更新操作.

android:configChanges="orientation|screenSize|smallestScreenSize|locale|keyboardHidden"

切换时的log输出

10-15 09:01:10.812  4799  4799 D MainActivity_life: onCreate: 
10-15 09:01:10.995  4799  4799 D MainActivity_life: onStart: 
10-15 09:01:11.011  4799  4799 D MainActivity_life: onResume: 
10-15 09:01:13.789  4799  4799 D MainActivity_life: onConfigurationChanged: 
10-15 09:01:17.997  4799  4799 D MainActivity_life: onConfigurationChanged:

3.Activity的四种启动模式
标准:是Activity的默认启动模式,对于AndroidManifest的Activity节点下的android:launchMode="standard"标签.
特定:每次启动都会重新创建新的Activity.
singleTop:对应的AndroidManifes的Activity节点下的android:launchMode="singleTop"标签
特点:当此模式的Activity处于栈顶时,不会重新创建新的Activity,会调用onNewIntent方法,如果更新Activity的intent,需要调用 setIntent()方法,具体的生命周期过程

10-15 09:14:17.662  5202  5202 D MainActivity_life: onCreate: 
10-15 09:14:17.759  5202  5202 D MainActivity_life: onStart: 
10-15 09:14:17.762  5202  5202 D MainActivity_life: onResume: 
//开始启动自己
10-15 09:14:19.998  5202  5202 D MainActivity_life: onPause: 
10-15 09:14:19.999  5202  5202 D MainActivity_life: onNewIntent: 
10-15 09:14:19.999  5202  5202 D MainActivity_life: onResume:

singleTask:在activity栈中已经有需要再启动的activity时,会先清除位于需要启动activity之上的activity,例如:启动顺序mainActivity-activityA -activityB-activityA,其中activityA是singleTask的启动模式:

10-15 09:22:28.238  5353  5353 D ActivityB_life: onCreate: 
10-15 09:22:28.241  5353  5353 D ActivityB_life: onStart: 
10-15 09:22:28.263  5353  5353 D ActivityB_life: onResume: 
10-15 09:22:28.989  5353  5353 D ActivityA_life: onStop: 
//在栈内已经存在一个ActivityA了,再去启动ActivityA.
10-15 09:22:37.114  5353  5353 D ActivityB_life: onPause: 
10-15 09:22:37.187  5353  5353 D ActivityA_life: onNewIntent: 
10-15 09:22:37.194  5353  5353 D ActivityA_life: onRestart: 
10-15 09:22:37.196  5353  5353 D ActivityA_life: onStart: 
10-15 09:22:37.196  5353  5353 D ActivityA_life: onResume: 
//activityB最后清除出栈,
10-15 09:22:37.791  5353  5353 D ActivityB_life: onStop: 
10-15 09:22:37.791  5353  5353 D ActivityB_life: onDestroy: 

singleInstance:在一个栈中单独存在的activity.
关于activity栈:是指用来管理activity一种"先进先出"的队列结构,查看activity对应栈的方法:Activity的getTaskId()方法,同一个栈的id值是相同的.adb shell dumpsys activity在终端查看栈结构,比如还是上面的activity启动顺序,不同是ActivityA这是设置成singleInstance,这是的栈结构:有两个TaskRecord,其中ActivityB和MainActivity位于同一个栈中.

    Running activities (most recent first):
      TaskRecord{21af354 #743 A=com.dwj.eventbusdemo U=0 StackId=1 sz=1}
        Run #2: ActivityRecord{56895eb u0 com.dwj.eventbusdemo/.ActivityA t743}
      TaskRecord{3d156bb #742 A=com.dwj.eventbusdemo U=0 StackId=1 sz=2}
        Run #1: ActivityRecord{5971090 u0 com.dwj.eventbusdemo/.ActivityB t742}
        Run #0: ActivityRecord{6bdb7fb u0 com.dwj.eventbusdemo/.MainActivity t742}

4.Activity开发中使用技巧:
<1>定义一个父Activity,在创建新的Activity时继承这个activity即可,将一些activity的公共设置可以设置在父activity中,比如获取每个Activity的名字,设置activity的窗体属性,同一管理activity的生命周期等,
<2>在启动的activity中定义静态方法,启动条件会显而易见:

//可以根据需要添加启动ActivityB的参数
 public static void start(Context context) {
        Intent starter = new Intent(context, ActivityB.class);
        context.startActivity(starter);
    }

<3>管理activity类,用来一键退出app.在父类Activity的创建和销毁时用来添加和移除Activity,在需要一键退出的地方调用静态finishAllActivity方法.

public class ActivityControler {
    private static final String TAG = "ActivityControler";
    private static final ArrayList<Activity> ACTIVITIES = new ArrayList<Activity>();

    public static void addActivity(Activity activity) {
        Log.d(TAG, "addActivity: ");
        if (!ACTIVITIES.contains(activity)) {
            ACTIVITIES.add(activity);
        }

    }

    public static void removeActivity(Activity activity) {
        Log.d(TAG, "removeActivity: ");
        if (ACTIVITIES.contains(activity)) {
            ACTIVITIES.remove(activity);
        }
    }

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

推荐阅读更多精彩内容

  • 转载注明出处://www.greatytc.com/p/c2c2ee4eb48a 1. 简介 本篇不针对于...
    王三的猫阿德阅读 2,130评论 2 5
  • 启动与销毁Activity 不同于使用 main() 方法启动应用的其他编程范例,Android 系统会通过调用对...
    安卓Boy阅读 1,765评论 3 5
  • Activity的生命周期 Activity的创建和销毁onCreate(): 执行Activity某些基本设置的...
    Showdy阅读 901评论 0 1
  • 悄悄地 时光 又轮转了一圈 谢了春红 绿了芭蕉 冷了清秋 枯了苍翠 而今 满地堆积 季节里的容颜 自风华 藏于心的...
    乌鸦一只阅读 248评论 2 4
  • 连载第一篇文章讲到了电子商务的一些趋势性的问题,无论是个人还是企业,都可以从事电子商务,建立网络生意! 那么,个人...
    心蓝MIKE阅读 174评论 0 2