探究活动Activity(2)界面跳转及生命周期

简介: 探究活动Activity(2)界面跳转及生命周期

1.使用Intent在活动中跳转

首先我们新建一个名为MyActivityTest的项目,其中我们将活动命名为FirstActivity,布局命名为first_layout.xml,记得勾选Generate Layout File ,如下图所示20190226225655742.png

Finish创建然后我们右键点击res→layout→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/first_layout"
    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.example.myactivitytest.FirstActivity">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!" />
</RelativeLayout>


然后我们对它进行修改,修改完之后如下图所示:


20190226230202689.png


我们给它里面放了一个Buttonkong控件,并创建了标识id。现在我们再创建一个活动,右键点击com.example.myactivitytest→New→Activity→Empty Activity,会弹出一个对话框,我们将这个活动命名为SecondActivity,并勾选Generate Layout File,给布局文件命名为second_layout,如下图所示:


20190226230746543.jpg


还是老样子,打开second_layout.xml,修改里面的布局,如下图所示


20190226231139478.jpg


我们也给它一个Button控件,并给了标识id。接下来打开FirstActivity,来写按钮响应事件及跳转方法


Button button_1 = (Button)findViewById(R.id.button_1);//实例化按钮
        button_1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //实例化Intent
                Intent intent = new Intent(FirstActivity.this,SecondActivity.class);
                startActivity(intent);
            }
        });


我们在onCreate()方法里面实例化一个按钮,通过按钮的点击响应事件启动监听,在监听方法onClick()里面实例化Intent。


Intent是Android程序各组件之间进行交互的一种重要方式,它不仅可以指明当前组件想要执行的动作,还可以在不同组件之间传递数据。Intent一般可被用来启动活动、启动服务以及发送广播等场景,我们来看启动活动。


首先构建出一个Intent,传入FirstActivity.this,作为上下文参数,传入SecondActivity.class作为目标活动,意思就是我们在FirstActivity这个活动的基础上打开SecondActivity这个活动,然后通过startActivity()方法来执行这个Intent。就可以实现页面的跳转。


20190227092004120.gif


可以看到已经成功跳转了,接着我们来看activity的生命周期。


2.Activity生命周期


活动的生命周期对任何Android开发者来说都非常重要。


2.1活动状态


活动有四种状态:运行状态、暂停状态、停止状态、销毁状态。


Activity类中定义了7个回调方法,覆盖了活动生命周期的每一个环节,下面详细介绍一下这7个方法。


onCreate() 这个方法会在活动第一次被创建的时候调用,我们可以在这个方法中完成活动的初始化操作,比如加载布局、绑定事件等。


onStart() 这个方法在活动有不可见变为可见的时候调用。


onResume() 这个方法在活动准备好和用户进行交互的时候调用。此时活动处于运行状态。


onPause() 这个方法在系统准备去启动或恢复另一个活动的时候调用。此时活动处于暂停状态

onStop() 这个在活动完全不可见的时候调用,他和**onPause()**的区别在于,如果启动的新活动是一个对话框式的活动,那么onPause()方法会得到执行,而onStop()方法不会执行(因为活动并不是完全不可见),此时活动处于停止状态。

onDestroy() 这个方法在活动被销毁之前调用,之后的活动将变为销毁状态,此时活动处于销毁状态。


活动又分为3种生存期:


完整生存期:活动在onCreate()方法和onDestroy()方法之间所经历的,就是完整生存期。


可见生存期:活动在onStart()方法和onStop()方法之间所经历的的,就是可见生存期。

前台生存期:活动在onResume()方法和onPause()方法之间所经历的就是前台生存期。

下面我们来实际体验一下活动的生命周期。


右键点击com.example.myactivitytest→New→Activity→Empty Activity,会弹出一个对话框,我们将这个活动命名为ThirdActivity,并勾选Generate Layout File,给布局文件命名为third_layout,如下图所示:


20190227102318123.png


然后我们进入AndroidManifest.xml文件,修改一下这个ThirdActivity的配置,如下图所示:


201902271026197.png


我们给它使用了一个android:theme属性,这是用于给当前活动指定主题的,我们用了@style/Theme.AppCompat.Dialog就是让这个活动使用对话框。

现在我们打开first_layout.xml,它里面只有一个按钮,用跳转到SecondActivity的,我们再创建一个按钮,并给上标识id。


<Button
        android:id="@+id/button_3"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Start ThirdActivity"/>

然后我们在FirstActivity对这个按钮进行相关的监听事件编辑。

代码如下:

Button button_3 = (Button)findViewById(R.id.button_3);
        button_3.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(FirstActivity.this,ThirdActivity.class);
                startActivity(intent);
            }
        });


和之前的代码没有什么出入,就是指定的按钮不同,及跳转的页面不同而已,现在我们在FirstActivity中添加那些回调方法,然后Log日志打印,来看看它的生命活动:

打开FirstActivity,图片如下:


20190227104358178.png

@Override
    protected void onStart(){
        super.onStart();
        Log.d(TAG,"onStart");
    }
    @Override
    protected void onResume(){
        super.onResume();
        Log.d(TAG,"onResume");
    }
    @Override
    protected void onPause(){
        super.onPause();
        Log.d(TAG,"onPause");
    }
    @Override
    protected void onStop(){
        super.onStop();
        Log.d(TAG,"onStop");
    }
    @Override
    protected void onDestroy(){
        super.onDestroy();
        Log.d(TAG,"onDestroy");
    }
    @Override
    protected void onRestart(){
        super.onRestart();
        Log.d(TAG,"onRestart");
    }

图片中日志打印在FirstAcvtivity这个活动中,然后在回调方法里面加了日志打印,onCreate()是已经重写了的,所以我们只需要打印就可以了,下面的代码部分有六个回调方法,我们在上面介绍的时候提到过。下面我们来运行一下这个项目,然后会进入到主界面:如下图所示


20190227105835270.png

那么这个时候回使用那些方法呢?


点击Android Studio最下方的Android Monitor


20190227110032658.png


可以看到方法是依次onCreate()、onStart()、onResume()。

现在我们点击第一个按钮Start SecondActivity跳转到第二个页面,然后看这个下面会执行那个回调方法。


20190227110703505.png



我们现在在SecondActivity的布局页面,可以看到先执行onPause(),再执行onStop()。我们这个时候再按返回键BACK返回到第一个界面,再看一下会执行那些回调方法。


20190227111005255.png


可以看到先执行onRestart(),然后onStart(),最后onResume()。

这时候我们点击Start ThirdActivty按钮会弹出一个对话框,


20190227113510971.jpg

此时会执行什么方法呢?


20190227113422284.jpg


执行onPause()方法,因为FirstActivity没有被完全覆盖所以不会执行onStart()方法。

这个时候我们点一下BACK返回到FirstActivity界面,会执行那些方法呢?


20190227113952657.jpg


只会执行onResume()方法。

如果我们这个时候按home键会怎么样呢?


20190227111235126.jpg


按home键返回手机主桌面,此时程序只是被挂起来在后台执行,并没有销毁,所以会执行onPause()和onStop()方法。之后再按一次返回程序才会被销毁,我们从手机桌面回到这个FirstActivity的主界面会执行那些方法呢。看一下


2019022711155144.jpg


有没有发现很熟悉,没错,这个和我们在SecondActivity界面返回到FirstActivty界面时执行的方法一样,不信你回头去看。那么现在我们再点一下返回,程序就会被销毁,真正意思上的退出。


20190227111856902.jpg



程序先执行onPause(),然后onStop(),最后onDestroy()。销毁退出程序。

现在只是一个活动的声明周期,如果我们给SecondActivity也加上打印来看看,会是怎么执行的,SecondActivity代码如下。


package com.example.myactivitytest;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
public class SecondActivity extends AppCompatActivity {
    private static final String TAG = "SecondActivity";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(TAG,"Second onCreate");
        setContentView(R.layout.second_layout);
        Button button_2 = (Button)findViewById(R.id.button_2);
        button_2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(SecondActivity.this,FirstActivity.class);
                startActivity(intent);
            }
        });
    }
    @Override
    protected void onStart(){
        super.onStart();
        Log.d(TAG,"Second onStart");
    }
    @Override
    protected void onResume(){
        super.onResume();
        Log.d(TAG,"Second onResume");
    }
    @Override
    protected void onPause(){
        super.onPause();
        Log.d(TAG,"Second onPause");
    }
    @Override
    protected void onStop(){
        super.onStop();
        Log.d(TAG,"Second onStop");
    }
    @Override
    protected void onDestroy(){
        super.onDestroy();
        Log.d(TAG,"Second onDestroy");
    }
    @Override
    protected void onRestart(){
        super.onRestart();
        Log.d(TAG,"Second onRestart");
    }
}

注意到,我在SecondActivity的打印里面加了一个Second,用于和FirstActivity的打印日志区分,然后启动项目,点击Start SecondActivity到第二个页面看看。


20190227195757604.png


可以看到,先执行FirstActivity的onPause()方法,然后跳转到SecondActivity页面,跳转的同时执行SecondActivty的onCreate()、onStart()、onResume()。最后是FirstActivity的onStop()方法(和你想的是不是一样的呢),然后我们点击SecondActivty页面上的Retrun FirstActivity按钮返回,再看看会执行什么方法。


20190227200413348.png


注意看和刚才FirstActivity跳转SecondActivity所执行的方法是一样的,那么我们在SecondActivity页面按BACK键返回到FirstActivity和用页面按钮跳转会是一样的吗?


20190227200722248.png


可以看到我们用BACK键返回会执行SecondActivity的onPause()方法,然后执行FirstActivity的onRestart()、onStart()、onResume()。然后执行SecondActivity的onStop()、onDestroy()。和我们刚才用按钮返回不一样。这个就和活动的启动模式有关了,了解活动的生命周期是为了更好的利用手机的存储空间,优化用户体验,这在实际开发中非常重要,相信通过这个例子,你应该了解了,我是初学者-Study。




相关实践学习
通过日志服务实现云资源OSS的安全审计
本实验介绍如何通过日志服务实现云资源OSS的安全审计。
相关文章
|
4月前
|
监控 Java 开发工具
Android 崩溃监控实战:一次完整的生产环境崩溃排查全流程
某 App 新版上线后收到大量用户投诉 App 闪退和崩溃。仅凭一条崩溃日志和会话追踪,团队如何在2小时内锁定「快速刷新导致数据竞态」这一根因?本文带你复现真实生产环境下的完整排查路径:从告警触发、堆栈分析、符号化解析,到用户行为还原——见证 RUM 如何让“无法复现的线上崩溃”无所遁形。
608 60
|
XML 缓存 前端开发
Android 架构之 MVI 初级体 | Flow 替换 LiveData 重构数据链路(下)
Android 架构之 MVI 初级体 | Flow 替换 LiveData 重构数据链路
986 0
|
IDE Java API
Gradle 系列(2)手把手带你自定义 Gradle 插件
Gradle 系列(2)手把手带你自定义 Gradle 插件
1560 0
Gradle 系列(2)手把手带你自定义 Gradle 插件
|
算法 调度 Python
深入理解操作系统中的进程调度算法
在操作系统中,进程调度是核心任务之一,它决定了哪个进程将获得CPU的使用权。本文通过浅显易懂的语言和生动的比喻,带领读者了解进程调度算法的重要性及其工作原理,同时提供代码示例帮助理解。
|
Linux C++ iOS开发
【C++ 17 新特性 文件管理】探索C++ Filesystem库:文件和目录操作的全面指南(二)
【C++ 17 新特性 文件管理】探索C++ Filesystem库:文件和目录操作的全面指南
2288 2
|
存储 API 数据库
Kotlin协程与Flow的魅力——打造高效数据管道的不二法门!
在现代Android开发中,Kotlin协程与Flow框架助力高效管理异步操作和数据流。协程采用轻量级线程管理,使异步代码保持同步风格,适合I/O密集型任务。Flow则用于处理数据流,支持按需生成数据和自动处理背压。结合两者,可构建复杂数据管道,简化操作流程,提高代码可读性和可维护性。本文通过示例代码详细介绍其应用方法。
469 2
|
Shell Serverless
makefile 函数全解
makefile 函数全解
971 0
makefile 函数全解
|
存储 安全 Java
【Java】已解决Java中的java.lang.VerifyError异常
【Java】已解决Java中的java.lang.VerifyError异常
1382 1
|
缓存 算法 NoSQL
短信验证码登录接口,如何防止恶意攻击
该文讨论了移动应用中常见的手机短信验证码登录(短验登录)的安全设计。后端通常需要提供获取短信验证码和手机短验登录两个API。为了增强机短验登录API的安全性,提出了几种无需依赖Redis等存储介质的方案:1)使用数字签名确保请求合法性;2)基于时间戳的验证,允许在一定时间范围内有效;3)应用TOTP算法生成动态码进行验证;4)利用JWTToken进行身份验证并设置有效期。文章强调了创新思考在解决安全问题中的重要性,并鼓励读者分享更多方案。
1302 1
|
Android开发 UED
Android Activity的生命周期详解
Android Activity的生命周期详解
312 0

热门文章

最新文章