Android四大组件——Activity——Activity的生命周期
Activity状态:
每个Activity在其生命周期中最多可能有四种状态
1.运行状态:处于栈顶时。初次创建处于栈顶时依次调用:onCreate(),onStart(),onResume()。由不可见重新处于栈顶时依次调用:onRestart(),onStart(),onResume()。由可见重新处于栈顶时调用:onResume()。
2.暂停状态:可见却不在栈顶。例如在MainActivity中启动一个对话框式Activity时。该对话框式Activity处于栈顶,但MainActivity仍然可见,只是MainActivity不处于栈顶。调用onPause()。如下图:
3.停止状态:不可见并且不在栈顶时。例如在MainActivity中启动一个普通的Activity时,该Activity会彻底覆盖MainActivity,致使MainActivity不可见,这时MainActivity便进入了停止状态。依次调用onPause(),onStop()
4.销毁状态:从栈中移除后。例如在MainActivity界面按下返回键,这时是将MainActivity从栈顶移除,这样被移除后的MainActivity就成了销毁状态。依次调用onPause(),onStop(), onDestroy()
onCreate():该方法会在Activity第一次被创建的时候调用。我们一般都会重写此方法,完成一些Activity的初始化操作,如加载布局,绑定事件等。该方法使得Activity创建。
onStart():该方法在Activity由不可见变为可见时调用。使得Activity可见。
onResume():该方法在Activity准备好和用户进行交互时调用。此时的Activity一定返回栈的栈顶,并且处于运行状态。使得Activity获取焦点,可以进行操作(交互)
onPause():该方法在系统准备去启动或者恢复另一个Activity的时候调用,我们通常会在这个方法中将一些消耗CPU的资源释放掉,以及保存一些关键数据,但这个方法的执行速度一定要快,不然会影响到新的栈顶Activity的使用。使得Activity失去焦点,不能交互。
onStop():该方法在Activity完全不可见的时候调用。它和onPause()方法的主要区别在于,如果启动一个新的Activity是一个对话框式的Activity,那么onPause()方法会得到新的执行,而onStop()方法并不会执行。使得Activity不可见
onDestroy():该方法在Activity被销毁之前调用,之后Activity的状态将变为销毁状态。使得Activity销毁。
onRestart():该方法在Activity由停止状态变为运行状态之前调用。也就是Activity被重新启动了。
1.创建三个Activity:MainActivity , AActivity(普通的Activity) , BActivity(对话框式Activity)
怎么将 BActivity设成对话框式?在AndroidManifest.xml中的<.activity>标签中
<activity android:name=".BActivity"
android:theme="@style/Theme.AppCompat.Dialog">
</activity>
通过android:theme="@style/Theme.AppCompat.Dialog"指定当前Activity主题为对话框式。
2.修改MainActivity的代码:
package com.java.androidstudy; import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button; public class MainActivity extends AppCompatActivity {
private Button normal_btn;
private Button dialog_btn;
private String tag = "MainActivity"; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(tag,"onCreate");
setContentView(R.layout.activity_main);
initView();
normal_btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this,AActivity.class);
startActivity(intent);
}
}); dialog_btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this,BActivity.class);
startActivity(intent);
}
});
} private void initView(){
normal_btn = findViewById(R.id.a_btn);
dialog_btn = findViewById(R.id.b_btn);
} @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()");
} }
点击运行后,如下图:
此刻观看日志:
可以发现当MainActivity第一次被创建时会依次执行onCreate(),onStart(),onResume()
点击第一个按钮:启动普通的Activity,这时会启动AActivity,该AActivity入栈,位于栈顶,会将MainActivity完全遮挡住,因此onPause() 和 onStop()都会得到执行。
查看日志:
依次执行了onPause() 和 onStop()
点击退出:
之前被遮挡住的MainActivity此时处于停止状态,点击退出时,AActivity出栈,MainActivity重新处于栈顶,由停止状态变为运行时状态。所以先调用onRestart(),之后会依次执行onStart()和onResume()。注意,此时onCreate()方法不会执行,因为MainActivity没有重新创建。
点击第二个按钮:启动对话框式Activity。如下图:
观察日志:
此时只执行了onPause(),没有执行onStop()方法。这是因为对话框式的BActivity并没有完全遮挡住MainActivity,此时的MainActivity只是进入了暂停状态。(之前启动AActivity时,MainActivity进入了停止状态。),相应的,按下返回键,也只有onResume()方法会得到执行。如下:
最后在MainActivity界面按下返回键,此时日志信息如下:
依次执行onPause(),onStop(),onDestroy().销毁MainActivity.
具体实践:
1.onCreate()和onDestory()的使用
onCreate():第一次创建Activity的时候调用
onDestory():销毁Activity的时候调用
修改MainActivity的布局:添加两个输入。
现在的输入框,若是我输入到一半,突然退出,再次进入就要重新输入。但是我不想那么麻烦,我希望输入框能自动显示上次退出前的内容。
分析:在Activity销毁前将输入框中的内容保存,再次启动Activity时将保存的内容显示到输入框。(l类似于记住密码功能)
Activity销毁前保存数据:需要在onDestroy()中操作
Activity再次启动时显示数据:需要在onCreate中操作
代码如下:
package com.java.androidstudy; import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText; public class MainActivity extends AppCompatActivity {
private Button normal_btn;
private Button dialog_btn;
private String tag = "MainActivity";
private EditText user;
private EditText password; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(tag,"onCreate");
setContentView(R.layout.activity_main);
initView();
displayinfo(); } private void initView(){
normal_btn = findViewById(R.id.a_btn);
dialog_btn = findViewById(R.id.b_btn);
user = findViewById(R.id.user);
password = findViewById(R.id.password);
} private void displayinfo(){
String content_user = getSharedPreferences("myinfo",0).getString("user","");
String content_pwd = getSharedPreferences("myinfo",0).getString("pwd","");
user.setText(content_user);
password.setText(content_pwd);
} @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()");
//获取输入的内容
String content_user = user.getText().toString();
String content_password = password.getText().toString(); //使用SharedPerences存储数据
SharedPreferences.Editor editor = getSharedPreferences("myinfo",0).edit();
editor.putString("user",content_user);
editor.putString("pwd",content_password);
editor.apply();
} @Override
protected void onRestart() {
super.onRestart();
Log.d(tag,"onRestart()");
} }
运行效果如下:
会自动将上次退出时的内容显示出来。
2.onStart()和onStop的使用
onStart():此时可见,没有焦点,也就是不可以进行操作
onStop():此时不可见。没有焦点
package com.java.androidstudy; import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
/*
有这样一个需求:当正在看电影的时候,突然打来电话,如果接听电话,而电影也在播放,杂音十分影响使用感。
现在需要接听电话时电影自动暂停,挂断电话后电影继续播放。
分析:接电话时会依次执行onPause()和onStop()方法,所以我们可以在onStop()方法中暂停电影
挂断电话回答该界面时会依次执行onRestart(),onStart(),onResume。我们可以在onStart()中继续播放电影
*/
public class AActivity extends AppCompatActivity { private static final String TGA = "AActivity";
private TextView play;
private Button play_control;
private boolean isPlay = false;
private boolean isStopAtAmin = false;//是否是因为生命周期的变化而主动停止的
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_a);
Log.d(TGA,"onCreate");
initView();
initListener();
} private void initView() {
play = findViewById(R.id.play);
play_control = findViewById(R.id.play_control);
} private void initListener(){
play_control.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(isPlay){//如果当前状态是播放的,点击该按钮后就暂停播放,并将按钮上的文字显示为播放
stop();
}else { //如果当前状态是暂停的,点击该按钮后变为播放状态,并将按钮上的文字显示为暂停
play();
}
}
});
} private void stop() {
Log.d(TGA,"暂停电影");
play.setText("电影已经暂停!!!");
play_control.setText("播放");
isPlay = false;
} private void play() {
Log.d(TGA,"播放电影");
play.setText("正在播放电影!!!");
play_control.setText("暂停");
isPlay = true;
} @Override
protected void onStart() {
super.onStart();
Log.d(TGA,"onStart()");
if (isStopAtAmin){ //如果是因为生命周期结束停止的,在重新回到栈顶时播放电影
play();
isStopAtAmin = false;
}
} @Override
protected void onStop() {
super.onStop();
Log.d(TGA,"onStop() ");
if (isPlay){//如果当前是播放的,那么我们需要将这个电影停掉。
stop();
isStopAtAmin = true;
}
} @Override
protected void onResume() {
super.onResume();
Log.d(TGA,"onResume()");
} @Override
protected void onPause() {
super.onPause();
Log.d(TGA,"onPause()");
} @Override
protected void onRestart() {
super.onRestart();
Log.d(TGA,"onRestart()");
} @Override
protected void onDestroy() {
super.onDestroy();
Log.d(TGA,"onDestroy()");
}
}
运行如下:
点击播放电影:
此刻接听电话:右下图,可以发现依次执行了onPause(),onStop()。然后暂停电影
此刻挂断电话:可以看到依次执行了onRestart(),onStart(),onResume()。并在start()方法中自动播放电影。
3.onResume() 和 onPause()
onResume():onstart()可见之后在这里获取到焦点,可以进行操作。
onPause():失去焦点,不可以操作。
当从FirstActivity跳转到SecondActivity后,SecondActivity至于栈顶处于可见状态,而FirstActivity进入停止状态(如果SecondActivity是对话框式的Activity,则FirstActivity进入暂停状态),在SecondActivity界面点击返回键后,SecondActivity出栈(销毁),这时FirstActivity重新处于栈顶,执行onRestart()方法,再依次执行 onStart(),onResume()。
注意:这里不止对话框式Activity(透明主题也可以),只要FirstActivity仍然可见,就不会执行onStop()方法使之进入停止状态(该状态不可见),而是只执行onPasue()方法使之进入暂定状态(该状态失去焦点,不可点击)
代码:
package com.java.androidstudy; import androidx.appcompat.app.AppCompatActivity; import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button; public class FirstActivity extends AppCompatActivity {
private static final String TGA = "FirstActivity";
private Button btn_first; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_b);
Log.d(TGA,"onCreate");
initView();
initListener();
} private void initListener() {
btn_first.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(FirstActivity.this,SecondActivity.class);
startActivity(intent);
}
});
} private void initView() {
btn_first = findViewById(R.id.btn_first);
} @Override
protected void onStart() {
super.onStart();
Log.d(TGA,"onStart()");
} @Override
protected void onStop() {
super.onStop();
Log.d(TGA,"onStop() ");
} @Override
protected void onResume() {
super.onResume();
Log.d(TGA,"onResume()");
} @Override
protected void onPause() {
super.onPause();
Log.d(TGA,"onPause()");
} @Override
protected void onRestart() {
super.onRestart();
Log.d(TGA,"onRestart()");
} @Override
protected void onDestroy() {
super.onDestroy();
Log.d(TGA,"onDestroy()");
}
}
然后将SecondActivity的主题改成透明主题:
<activity android:name=".SecondActivity"
android:theme="@android:style/Theme.Translucent">
</activity>
运行效果:
点击按钮后:
可以看到第二个页面弹出来了,但是第一个页面仍然可见,只是失去了焦点,不能点击。
看看日志:
FirstActivity只是进入了暂停状态,失去焦点。
点击返回键,使得SecondActivity销毁。查看日志:
这时FirstActivity重新进入栈顶,获取焦点。
横竖屏切换Activity生命周期的变化
MainActivity:
package com.java.androidstudy; import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log; public class MainActivity extends AppCompatActivity {
private String tag = "MainActivity"; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(tag,"onCreate");
setContentView(R.layout.activity_main);
} @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()");
} }
运行后:
查看日志:
现在旋转成横屏:
再来看看完整的生命周期变化:
红框内的为横屏后的变化。
可以看到:在点击横屏后,是先将原Activity销魂,再创建新的Activity
再将其从横屏切换为竖屏:
与竖屏切换横屏一样,都会先销毁Activity再重新创建。
横竖屏切换的问题:
如:将看到一半的电影切换成横屏,因为切换后是创建新的Activity,所以会造成进度条清零,需要手动去拉进度条,这种体验无疑是极差的
如:
package com.java.androidstudy; import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.SeekBar; public class MainActivity extends AppCompatActivity {
private String tag = "MainActivity";
private SeekBar progress; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(tag,"onCreate");
setContentView(R.layout.activity_main);
initView(); } private void initView() {
progress = findViewById(R.id.progress);
progress.setMax(100);
progress.post(new Runnable() {
@Override
public void run() {
progress.setProgress(0); //每次初始化的时候进度条清零
}
});
} @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()");
} }
切换前:
此时进度条到一半。
切换成横屏:
可以看见进度条自动清零了。
怎么解决:
第一种:禁止屏幕旋转,指定屏幕方向。(适合只有一种屏幕状态的应用开发配置)
<activity android:name=".MainActivity"
android:screenOrientation="landscape">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
android:screenOrientation="landscape" //指定为横屏
android:screenOrientation="portrait" //指定为竖屏
这样指定后的横竖屏切换不会销毁原来的Activity再创建新的Activity。
第二种:设置配置信息改变不影响。(适合有两种/多种屏幕状态的应用开发,如:视频播放器)
<activity android:name=".MainActivity"
android:configChanges="keyboardHidden|screenSize|orientation">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
android:configChanges="keyboardHidden|screenSize|orientation" //对键盘隐藏,屏幕大小,屏幕方向都不敏感
当其中一个发生变化时,生命周期不受影响。
Android四大组件——Activity——Activity的生命周期的更多相关文章
- Android四大组件之——Activity的生命周期(图文详解)
转载请在文章开头处注明本博客网址:http://www.cnblogs.com/JohnTsai 联系方式:JohnTsai.Work@gmail.com [Andro ...
- Android四大组件之——Activity的开启:StartActivity()和StartActivityForResult()(图文详解)
如需转载请在文章开头处注明本博客网址:http://www.cnblogs.com/JohnTsai 联系方式:JohnTsai.Work@gmail.com ...
- 【Android开发日记】之入门篇(四)——Android四大组件之Activity
在Android中,无论是开发者还是用户,接触最多的就算是Activity.它是Android中最复杂.最核心的组件.Activity组件是负责与用户进行交互的组件,它的设计理念在很多方面都和Web页 ...
- Android四大组件之Activity(活动)及其布局的创建与加载布局
Android四大组件之Activity(活动)及其布局的创建与加载布局 什么是Activity ? 活动(Activity)是包含用户界面的组件,主要用于和用户进行交互的,一个应用程序中可以包含零个 ...
- Android 四大组件之Activity生命周期
写这篇博文之前,已经对android有一定的了解和认识.这篇博文主要讲述android的Activity的生命周期,这是android开发者必须掌握的知识.android的Activity组件拥有7个 ...
- 深入剖析Android四大组件(一)——Activity生命周期具体解释
1.管理Activity的生命周期 不管是正在执行的Activity还是没有执行的Activity,它们都接受Android的框架管理,这使得Activity处于不同的生命周期. ①Activity的 ...
- Android 四大组件之 Activity(一)
1.Activity的定义及作用: Android系统中的四大组件之一,可以用于显示View.Activity是一个与用户交互的系统模块,几乎所有的Activity都是和用户进行交互的一个应用程序的组 ...
- Android 四大组件之 Activity(二)
1.综述 Activity是Android四大组件(Application Components)之一,简单来说Activity就是平常所见到的用户界面,一般情况下,一个Activity所占的窗口是满 ...
- Android四大组件及activity的四大启动模式
Android四大组件 1. 广播接收者的两种类型: (1)系统广播接收者,就是继承BroadcastReceiver这个类,然后还要在清单文件中注册,注册之后给他一个action.当系统发生了这个a ...
- Android四大组件之——Activity(一)定义、状态和后退栈(图文详解)
什么是Activity 关键字:应用组件.四大组件.用户界面,交互. An Activity is an application component that provides a screen wi ...
随机推荐
- 前端好用API之Fullscreen
前情 在前端开发需求中,特别网页有视频需求时,需要做视频全屏功能,或者在某些可视化大屏项目也要做全屏. Fullscreen介绍 让你可以简单地控制浏览器,使得一个元素与其子元素,如果存在的话,可以占 ...
- 内网渗透----Linux下信息收集
基础信息 1.系统类型 cat /etc/issue查看系统名称 Lsb-release查看系统名称.版本号 2. 内核版本 uname –a 查看所有信息 ls /root |grep vmlinu ...
- C# XML基础入门(XML文件内容增删改查清)
前言: 最近对接了一个第三方的项目,该项目的数据传输格式是XML.由于工作多年只有之前在医疗行业的时候有接触过少量数据格式是XML的接口,之后就几乎没有接触过了.因此对于XML这块自己感觉还是有很多盲 ...
- synchronized底层实现原理及锁优化
一.概述 1.synchronized作用 原子性:synchronized保证语句块内操作是原子的 可见性:synchronized保证可见性(通过"在执行unlock之前,必须先把此变量 ...
- 什么是 Executors 框架?
Executor 框架是一个根据一组执行策略调用,调度,执行和控制的异步任务的框 架. 无限制的创建线程会引起应用程序内存溢出.所以创建一个线程池是个更好的的 解决方案,因为可以限制线程的数量并且可以 ...
- Java 中 ConcurrentHashMap 的并发度是什么?
ConcurrentHashMap 把实际 map 划分成若干部分来实现它的可扩展性和线程安 全.这种划分是使用并发度获得的,它是 ConcurrentHashMap 类构造函数的一 个可选参数,默认 ...
- MySQL 如何优化 DISTINCT?
DISTINCT 在所有列上转换为 GROUP BY,并与 ORDER BY 子句结合使用. SELECT DISTINCT t1.a FROM t1,t2 where t1.a=t2.a;
- 您对 Distributed Transaction 有何了解?
分布式事务是指单个事件导致两个或多个不能以原子方式提交的单独数据源的突 变的任何情况.在微服务的世界中,它变得更加复杂,因为每个服务都是一个工 作单元,并且大多数时候多个服务必须协同工作才能使业务成功 ...
- 学习Cobbler(一)
一. http://cobbler.github.io/ Cobbler is a Linux installation server that allows for rapid setup of n ...
- 学习SVN01
SVN服务器搭建实录 第一章 SVN介绍 1.1 什么是SVN(subversion) SVN是近年来崛起的非常优秀的版本管理工具,与CVS管理工具一样,SVN是一个固态的跨平台的开源的版本控制 ...