详解Activity的生命周期以及通信--Intent的基础用法与高级用法详解

引入:对于新手来说,不了解Activity的生命周期以及通信则非常容易产生这样一个问题:这段代码为什么跑起来了?这段代码为什么跑不了?
原因:Activity有自己的生命周期方法以及通信原理,然后通过系统的回调机制,互相调用。
主题:Activity的生命周期以及通信的详解

一:Activity的生命周期方法:
1.onCreat();
活动开始前系统调用:
2.onStart();
活动开始时系统调用:
3.onResume();
活动在进行时系统调用:
4.onRestart();
活动不在视野内但又不被摧毁时重新回到视野内系统调用:(即按下home键后然后重新点进来)
5.onPause();
活动暂定时调用,即活动在视野内但出现线程阻塞时调用,比如出现警告窗口时就会触发
6.onStop();
活动不在视线范围内但又不被摧毁时系统调用;
7.onDestroy()
活动被摧毁时系统调用(即按下back键)

=================================================
理论知识是枯燥的,自己动手实验才是最有趣的,下面直接撸码:

public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.e(TAG, "onCreate: ");

    }

    @Override
    protected void onStart() {
        super.onStart();
        Log.e(TAG, "onStart: ");
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.e(TAG, "onResume: " );
    }

    @Override
    protected void onRestart() {
        super.onRestart();
        Log.e(TAG, "onRestart: " );
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.e(TAG, "onPause: " );
    }


    @Override
    protected void onStop() {
        super.onStop();
        Log.e(TAG, "onStop: " );
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.e(TAG, "onDestroy: ");
    }
    
}

首先:跑一下程序,即刚进入到活动的运行结果:
在这里插入图片描述
然后我们按下home键:
在这里插入图片描述
接着在页面没有被摧毁的状态下重新进入到页面:
在这里插入图片描述
最后我们按下back键:
在这里插入图片描述
系统的回调机制很奇妙对吧,当然你可以自己操作进行尝试,这将会更加有趣并且印象更深刻,测试代码就在上面,欢迎拿去使用

当然了解生命周期后你就可以利用生命周期进行各种功能的实现,比如但播放视频暂停时你要怎么做,当出现弹窗后客户页面被卡死时我们后台要如何去执行特定的操作等等,

二. Activity之间的通信方式------Intent意图跳转

由于Intent的隐式用法不常用,因此在这我只对Intent的显式用法进行详解

我们先讲活动之间的跳转,再讲数据的传递、
首先我们还是需要获取Intent对象,代码如下:

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

获取Intent参数解析:第一个参数是目前Activity的Context对象,这里传入自身就行了,第二个参数是要跳转到的Activity对象
第二行代码就是开启这个意图,该方法在Activity类中
我先加入一个Button来启动这个activity比较方便展示,代码如下

        Button bt1 = (Button) findViewById(R.id.bt1);
        bt1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                Bundle bundle = new Bundle();
                bundle.putString("name","秃头小郑");
                bundle.putInt("age",20);
                Intent intent = new Intent(MainActivity.this, MainActivity2.class);
                intent.putExtra("name","秃头小郑")
                        .putExtra("age",20);
//                      .putExtras(bundle)
                startActivity(intent);
            }
        });

按下跳转到第二个ACTIVITY按钮后 运行结果如下:
在这里插入图片描述
在这里插入图片描述
这样就成功跳转到第二个页面来了
那么问题来了,我们在第一个页面跳转的时候的数据怎么带过来呢?
这就需要用到我们的Intent的通信了

Intent通信方式(一):携带基础数据类型:
在这里插入图片描述
Intent对象可以使用putExtras()方法传递基本类型数据,因为方式差不多,所以我就简单地撸了几行,用法参数都差不多,第一个参数是名字(即Key),第二个参数是值(即Value),可以联想Map的映射去记忆。
下面开始撸码:这里也可以使用链式调用,不用讲究顺序
第一个activity中传递数据时:

           intent.putExtra("name","秃头小郑")
                 .putExtra("age",20);

跳转到的activity接受到数据时:

        Intent intent = getIntent();
        String name = intent.getStringExtra("name");
        int age = intent.getIntExtra("age",0);
        Log.e("MainActivity2", "我是 "+ name + ", " + age + " 岁了。" );

上面获取age时传入的第二个参数是个当获取不到”age“时传回来的默认值,这里随便写个0就行
然后我们跑一下程序:
在这里插入图片描述
这样我们就接收到从该activity传回来的数据了

二. Intent传递Bundle类型:
Bundle类只是一个对数据进行包装的类,有很多的putXXXX方法,这里不详细讲解
第一个activity中的代码:

                Bundle bundle = new Bundle();
                bundle.putString("name","秃头小郑");
                bundle.putInt("age",20);
                intent.putExtras(bundle);

第二个activity的代码:
声明:在activity接收到的Bundle时会自动进行拆装
因此代码与第一个获取数据时是一模一样的

        Intent intent = getIntent();
        String name = intent.getStringExtra("name");
        int age = intent.getIntExtra("age",0);
        Log.e("MainActivity2", "我是 "+ name + ", " + age + " 岁了。" );

上面的用法只能传递基本数据类型,不能传递对象,那么再来讲下Intent的高阶用法,传递对象参数。
三.高阶用法之----传递Serialzable对象
intent里面有个方法去传递Serialzable对象:
在这里插入图片描述
操作如下:只需要传递的对象去实现Serialzable接口就可以传递了
代码如下:

public class Worker implements Serializable {


    private String name;
    private int age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

}

行了,现在可以开始传递了,
第一个activity:

                Worker worker = new Worker();
                worker.setName("秃头小郑");
                worker.setAge(20);
                intent.putExtra("worker",worker);

第二个activity:

        Worker worker = (Worker) intent.getSerializableExtra("worker");
        String name = worker.getName();
        int age = worker.getAge();
        Log.e("MainActivity2", "我是 "+ name + ", " + age + " 岁了。" );

声明一点,这里一定要强制转换类型,因为源码接收的不是泛型,不会自动转成相应的对象在这里插入图片描述

跳转后运行结果:
在这里插入图片描述

三.Intent高阶用法之:传递Parcelable对象
这个用法相对比较复杂,底层有涉及到C语言指针问题,是个坑
在这里插入图片描述
用法:依旧是使用的对象类去实现Parcelable接口,但略有不同,因为重新了几个Parcelable需要用到的抽象方法,话不多说直接开撸:

public class Student implements Parcelable {

    public Student(){}
    public String name;
    public int age;

//TODO 注意: 读的顺序要和写的顺序一直,否则会报错,因为写的操作的API是由C语言的指针写的,所以可能读取到的长度不一致
//从Parcel对象中获取相关的数据,该方法是在跳转到的活动里被调用,即跳转后的页面获取数据时调用
    public Student(Parcel in) {
        name = in.readString();
        age  = in.readInt();
    }

//系统为了扩展一些功能用的,这里不理它
    @Override
    public int describeContents() {
        return 0;
    }

    //从跳转前的活动写数据到Parcel的对象中,方便读的时候获取,读写顺序要一致,强调!!否则报错
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(name);
        dest.writeInt(age);
    }

    //CREATOR一定要有,系统自动生成,不需要我们改写
    public static final Creator<Student> CREATOR = new Creator<Student>() {
    //创建Student对象 并且在Parcel构建好后传递给Student对象,这样成员数据就可以从Parcel中获取了
        @Override
        public Student createFromParcel(Parcel in) {
            return new Student(in);
        }

        //辅助方法用不到,直接这么写就好
        @Override
        public Student[] newArray(int size) {
            return new Student[size];
        }
    };
}

各种方法的用法我都写在注释里了,各位直接看代码就行。

现在终于可以开始使用了.
第一个活动:

                Student student = new Student();
                student.name = "秃头小郑";
                student.age = 20;

第二个活动:

        Student student = intent.getParcelableExtra("student");
        String name = student.name;
        int age = student.age;
        Log.e("MainActivity2", "我是 "+ name + ", " + age + " 岁了。" );

这里与Serialzble对象的区别就是不用强制转成Student类,因为源码接收的是泛型。
在这里插入图片描述
跳转后运行结果:
在这里插入图片描述
到此Acitvity的生命周期以及通信的总结结束:希望能帮到想入门的开发人员哈,以身试坑,让各位少走弯路。
之后遇到更高级的用法会再一一分享。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值