Android基础 - Activity

老婆保佑,代码无BUG

目录

  • 生命周期
  • Activity保存当前状态
  • Activity之间的跳转
  • Activity 参数 回传
  • 启动模式
  • Activity完美退出的方法

一.Activity生命周期

一上来就是生命周期图,多少小伙伴,看到就头疼,不说了,都是泪啊。。。。


activity.png

独家解析,谈谈我的理解方式

  • onCreate()
    在Activity被创建时回调;这个不要多说
  • onStart()
    在Activity画面可视之前被回调,就是你能看到之前
  • onResume()
    在Activity界面可互动之前被回调,你现在可以随便点击了
  • onPause()
    回调后Activity不再可互动; 你现在不能点击了,没办法做交互
  • onStop()
    回调后Activity不再可视,你就看不到了
  • onDestroy()
    回调后Activity被销毁

是不是以一一对应的关系,这样记得话 我感觉很容易理解, 又方便记忆

撸一撸启动时候的生命周期怎么走

一个Activity的启动顺序

onCreate()——>onStart()——>onResume()

当另一个Activity启动时

第一个Activity onPause()——>
    第二个Activity             onCreate()——>
                              onStart()——>
                              onResume() ——>
第一个Activity onStop() 

当返回到第一个Activity时

第二个Activity onPause() ——> 
         第一个Activity onRestart()——>
                       onStart()——>
                       onResume() ——>
第二个Activity onStop()——>
              onDestroy()

用户按下Back键返回

onPause()——>onStop() 

如果新的Activity设置了透明主题,不会回调onStop() 透明主题看不到不代表没有啊

二.Activity保存当前状态

  • onSaveInstance
  • onRestoreInstance

这两个方法先有个印象,在应用程序设置改变(比如竖屏变横屏)、在内存不足需要腾出内存时,一个Activity可能被系统杀死(可能在之后重新启动),这时可能会造成信息的丢失,比如控件里暂时存放的数据、Activity对象里的属性值都会在Activity被系统杀死时丢失。 可以用onSaveInstance和onRestoreInstance来解决这个问题

来个例子

public class MainActivity extends Activity {
    private Button button;
    private TextView tv;
    private int num;
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        button = (Button) findViewById(R.id.button1);
        tv = (TextView) findViewById(R.id.textView1);
        button.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {//按钮一被点击
                num ++;//数字+1
                tv.setText(Integer.toString(num));//显示到TextView
            }
        });
    }
    //在Activity可能被系统杀死时回调,用来保存杀死前的一些状态,以便以后再启动时将保存下来的状态恢复到新的Activity
    //那些有id的控件的状态会默认被保存,在之后调用onRestoreInstanceState时再自动恢复
    //但是Activity类中的属性的值不会被自动保存,需要我们手动保存,保存到参数Bundle outState中
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);//这句是继承下来的默认逻辑,不要删除
        //将属性num的值以键值对的形式放进outState,键是一个字符串,名字随便起,但要见名知意,值就是要保存的值
        outState.putInt("number", num);//放进去以后即使这个Activity被销毁,这个Bundle里面的信息会被系统保存下来
    }
    //横竖屏切换Activity被杀死后,会马上再创建一个Activity,会回调这个方法去恢复原来丢失的信息
    //有id的控件的状态会自动恢复,但Activity属性的值需要我们在这个方法里手动恢复
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        //从系统维护的Bundle对象中取出之前保存进去的值,第一个参数是键,第二个参数是没有这个键值对情况下的默认值
        int n = savedInstanceState.getInt("number", 0);
//      tv.setText(Integer.toString(n));//将从Bundle中取出的数字转为字符串设置到TextView中
        num = n;//属性也要设置为取出来的值
    }
}

ps: 这排版看着怎么就那么难受呢 = =

三.Activity之间的跳转

activity之间的跳转,一般肯定用intent,至于不一般,在组件化中会使用路由,这玩意,还真是TM 挺麻烦的

(1)显示跳转

startActivity(new Intent(MainActivity.this,SecondActivity.class))

别忘了在manifest 添加activity

(2) 隐身跳转

在清单文件中注册action

  <activity android:name=".KfcActivity">
            <!-- 将这个KdfActivity的功能注册为吃,具体为com.qianfeng.EAT -->
            <intent-filter>
                <!-- 动作注册为com.qianfeng.EAT,一个这样的意图发给操作系统时,操作系统会找到这个符合条件的Activity并启动 -->
                <action android:name="com.allens.EAT"/>
                <category android:name="android.intent.category.DEFAULT"/><!-- 这个分类一定要写,不然会出错 -->
            </intent-filter>
        </activity>

activity中代码

Intent intent = new Intent("com.allens.EAT");// 创建一个意图,action为com.qianfeng.EAT
startActivity(intent);// 启动意图动作为com.qianfeng.EAT的一个Activity
// 启动后会将意图提交给操作系统,操作系统会在所以清单中扫描有没有一个Activity的action注册为com.qianfeng.EAT
// 如果有,就启动;如果一个也没有,就出错

如果有两个不同的Activity,拥有相同的action,系统会让用户去选择去哪个Activity

四.跳转传值

intent 传值

// 传递参数
Intent intent = new Intent(MainActivity.this,SecondActivity.class);
intent.putExtra("allens", s);
startActivity(intent);


//获取参数
String str = intent.getStringExtra("allens");

Bundle

Bundle bundle = new Bundle();
//往这个Bundle对象里以键值对形式放置信息
bundle.putString("inputtext", s)
//将这一捆信息一下子放进意图对象
intent.putExtras(bundle);

当然啦,一般我们都会传一些比较复杂的对象,比如在网络获取到的数据,需要调到一个详情界面,需要把获得的数据全部调到其他界面,简单来说,就是如何传递对象

这里给出两个东东

  • Parcelable
  • Serializable
    这两个都是接口,将对象序列化,然后传递到第二个Activity的

使用说明

//传递对象
  Bundle bundle = new Bundle();
  bundle.putSerializable("bundle_ser",person);//Parcelable 序列化对象
  intent.putExtras(bundle);


//获取对象
 Pen pen = (Pen)getIntent().getParcelableExtra("parcel_test");
intent.putExtra("tag1",data);// 序列化对象
Person per = (Person)intent.getSerializableExtra("tag1");

ps(大写的注意): 需要传递的对象都需要实现序列化接口,Android 中最好使用 Parcelable

至于二者的区别,我会在后期的文章中解释. 预知后事如何,请听下回分解


五.Activity 参数 回传

先记得这两个方法,后面解释

  • startActivityForResult
  • onActivityResult

有时候吧,我们需要一些参数,但是这些参数需要从第二个Activity中回传过来,哈哈,有借有还再借不能,PS 大兄弟们,救济救济我啊。。。最近穷死了 , 大写的哭

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Intent intent = new Intent(this, TwoActivity.class);
        //这里采用startActivityForResult来做跳转,此处的0为一个依据,可以写其他的值,但一定要>=0
        startActivityForResult(intent, 999);
    }


    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        //startActivityForResult 中的参数要相同
        if (requestCode == 999) {
            //和setResult中的参数相同
            if (resultCode == 110) {
                String data1 = data.getStringExtra("data");
                Log.e("TAG", "data--->" + data1);
            }
        }
    }
}

public class TwoActivity extends AppCompatActivity {

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Intent intent = new Intent();
        intent.putExtra("data", "测试的参数");
        //intent为A传来的带有Bundle的intent,当然也可以自己定义新的Bundle
        setResult(110, intent);
        finish();//此处一定要调用finish()方法
    }
}

六. 启动模式

这个问题,真心每次面试都会被问到,无奈

Activity 有4中启动模式,先说一下,然后慢慢解释

  • standard
  • singletop
  • singleTask
  • singleInstance

standard

默认的启动模式,也是标准的启动模式,打个比方,现在我们点击Button,启动当前的Activity,假设为Activity 的名字叫 A。 那么在任务栈中 就是
A A A A A A ......

稍等我一会,我去画个图 。说明一下

等待20分钟...


这太TM难画了

本着先后出的原则,任务栈中就是这样的,如果你想回退的话,只能 A3现出来,然后A2...

singletop

栈顶的两个Activity不会一样,如果栈顶有activity的实例, 则不需重新创建(只要不在栈顶就需要创建),可重用该实例,不过会调用onNewIntent()方法,如果栈顶不存在就重新创建新的实例并放入栈顶

在等我20分钟

不想吐槽了

看图,如果先启动A 然后启动 B 在启动A 那么任务栈中 是 A1 B A2 (从下往上看),如果此时 我们再次启动A 那么并不会想standard那样 再次启动一个 A 放入栈中,栈顶只有一个A 的实例,这就是singletop

singleTask

设置了singtask的Activity如果再一次启动,它就必须在最上面,如果有其他的在ta上面就会被弹出

这个不画图了,太丑了,我看不下去

意思很简单,谁设置了, 谁是老大,在栈顶

singleInstance

这种启动模式比较特殊,因为它会启用一个新的栈结构,将Acitvity放置于这个新的栈结构中,并保证不再有其他Activity实例进入。

扯了这么多,MD 怎么用啊!!!!!!!!

  • AndroidManifest.xml配置

launchMode 属性就是对应的启动模式

<activity
            android:name=".SingleInstanceActivity"
            android:label="singleInstance launchMode"
            android:launchMode="singleInstance"
            android:taskAffinity="">
  • Intent Flags设置
Intent intent = new Intent(StandardActivity.this, StandardActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(intent);

七.Activity完美退出的方法

我的推荐方法是 写一个单例类,将所有的Activity 都放到一个集合中,要退出的时候,将集合中的Activity 全部finish

点击跳转到代码


写在最后

以前也文章,其实就是想起来就写写,后来就不一样了,直接不写了!!!然后东西全写在有道云上,其实也还不错,但是吧,为了炫耀一下那么漂亮的老婆,哈哈哈哈哈哈。

当然,也希望,入坑的小伙伴能够一起进步。

最后,祝我新婚快乐,哈哈 刚刚结婚

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

推荐阅读更多精彩内容