Android Studio教程03-Activtiy生命周期的理解
1. Activity
1.1. 安卓中的Activity定义和特性:
- 一个Activity就是一个屏幕页面
- 一个APP中有很多个Activity(打开邮件app,打开具体邮件)
- APP一般从MainActivity中启动的,当然了,这个也可以修改的
- APP内的Activity可以通过一些方法(Intent...)进行切换(打开邮件app -> 打开具体邮件)
- APP之间的Activity也可以互相切换(从浏览器页面 -> facebook页面)
1.2. 注册Activity
进入AndroidManifest.xml
在application
下添加一个activity
元素
1. Intent filters
:设置默认开启的activity
Intent filters
可以显示或者隐式的启动activity,我们可以利用这个属性来扩展activity功能
<activity
android:name=".MainActivity"
android:label="FirstPage"
android:icon="@drawable/app_icon">
<!--intent-filter放在哪个activity,这个actiivty就是默认启动的activity-->
<intent-filter>
<!--action:这个activity可以发送数据-->
<action android:name="android.intent.action.SEND" />
<!--category:这个activity可以接收请求-->
<category android:name="android.intent.category.DEFAULT" />
<!--data:这个activity可以接收数据类型-->
<data android:mimeType="text/plain" />
</intent-filter>
</activity>
<activity
android:name=".SecondActivity"
android:label="SecondPage"
></activity>
程序调用过程
// Create the text message with a string
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.setType("text/plain");
sendIntent.putExtra(Intent.EXTRA_TEXT, textMessage);
// Start the activity
startActivity(sendIntent);
1.3. Activity的启动流程
插入activity01.md
插入activity02.md
1.4. 如何控制activity中的内容
通过代表控件的对象来更改控件内容
2. Android的生命周期
首先我们来看一下谷歌官网发布的图
声明周期函数 | 调用时机 | 所处状态 | 应该执行的操作 |
---|---|---|---|
onCreate |
在Activity对象第一次创建时调用 | Created | 初始化操作(只执行一次的操作) 调用 setContentView() 设置界面布局 |
onStart |
当Activity变得可见时调用该函数 | Started | 组件的初始化操作,建议放再onResume中 |
onResume |
当Activity开始准备与用户交互时调用该方法 | Resumed | 最常见的操作都需要放在这里(最重要的部分) |
onPause |
当系统即将开启另外一个Activity之前调用 | Paused | 停止一些可能影响电池的操作,清除一些轻度的占用CPU任务(关闭相机) |
onStop |
当前Activity变得不可见时调用 | Stopped | 当屏幕不可见的时候,清除或者调整一些操作 保存数据库的最好位置 |
onDestroy |
当前Activity被销毁之前将会调用 | 清除所有占用内存的任务 | |
onRestart |
当一个Activity再起启动之前会调用 | -> Resumed |
onCreate()
- 作用: 初始化 + 进入启动阶段
- 在Activity对象第一次被创建时调用,必须重写
- 那么在
onCreate()
应该执行一些什么操作呢?- 在整个生命周期只需要执行一次的操作
- 初始化 Activity 的必需组件
- 调用
setContentView()
来定义用户界面的布局
- 接收的参数为
savedInstanceState
:表示活动前所保存的状态,如果这个活动之前没有启动过,那么Bundle
的值为null
onCreate()
之后:进入启动阶段
TextView mTextView;
// some transient state for the activity instance
String mGameState;
@Override
public void onCreate(Bundle savedInstanceState) {
// 调用父类的onCreate方法
super.onCreate(savedInstanceState);
// recovering the instance state
if (savedInstanceState != null) {
mGameState = savedInstanceState.getString(GAME_STATE_KEY);
}
// 设置界面布局文件(res/layout/main_activity.xml)
setContentView(R.layout.main_activity);
// 初始化一些部件,这样在下面的方法中可以操作
mTextView = (TextView) findViewById(R.id.text_view);
}
// This callback is called only when there is a saved instance that is previously saved by using
// onSaveInstanceState(). We restore some state in onCreate(), while we can optionally restore
// other state here, possibly usable after onStart() has completed.
// The savedInstanceState Bundle is same as the one used in onCreate().
@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
mTextView.setText(savedInstanceState.getString(TEXT_VIEW_KEY));
}
// invoked when the activity may be temporarily destroyed, save the instance state here
@Override
public void onSaveInstanceState(Bundle outState) {
outState.putString(GAME_STATE_KEY, mGameState);
outState.putString(TEXT_VIEW_KEY, mTextView.getText());
// call superclass to save any view hierarchy
super.onSaveInstanceState(outState);
}
onStart()
- 作用: 使Activity可见,可视化页面会显示出来 + 进入Resume阶段
- 特性:
- 完成得特别快
- 一旦执行完成,直接进入
onResume()
阶段 - 所有生命周期组件会收到
onStart()
事件
onResume()
- 作用: app可以和用户交互
- 特性:
- app会一直停留在这个阶段,直到有什么操作打断他(来电话啦...)
- 所有生命周期组件会收到
onResume()
事件 - 当有异常时,会进入暂停阶段,处罚
onPause()
方法 - 当异常结束重新进入Resume阶段时,又会重新调用
onResume()
- 你应该在这段代码中写一些初始化组件的代码
- 建议: 如果在
onStart()
中初始化一些组件后,记得在onStop()
释放
onPause()
- 当acitivty不再前端的时候(即使在多窗口模式中,它是visible模式), app进入这个阶段
- 使用
onPause()
方法来停止或者调整操作,当activity
不再主界面的时候 - acitivity进入这个阶段的原因如下:
- 一些中断了app运行
- 多窗口模式下,一个app启动会自动让另外的app进入onpause状态
- 有些情况下,即使activity是visible模式,它也会进入这个onPause阶段
- 所有生命周期组件会收到
onPause()
事件,这里我们可以停止一些操作 - 这个阶段的任务:
- 可以停止一些你不想运行的操作(关闭camera..)
- 释放一些系统资源,处理sensors或者其他会影响电源的组件(但是推荐使用onStop()方法)
- 千万不要在这里保存数据,网络操作,或者数据库操作
- 注意: 完成这个阶段并不意味着activity离开了onPause阶段,如果acitivty进入Resume阶段,调用
onResume
,如果actiivty完全不可见,进入onStop()
阶段,否则一直在onPause
阶段
public class JavaCameraComponent implements LifecycleObserver {
...
// 一旦收到`onPause`事件。释放camera
@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
public void releaseCamera() {
if (camera != null) {
camera.release();
camera = null;
}
}
...
}
onStop()
- 什么时候发生:activity完全不可见
- 所有生命周期组件会收到
onStop()
事件,这里我们可以停止一些操作 - 在这个阶段的任务
- 释放一些heavy的任务
- 关闭一些CPU重的任务
- 这是保存到数据库的绝佳位置
@Override
protected void onStop() {
// call the superclass method first
super.onStop();
// save the note's current draft, because the activity is stopping
// and we want to be sure the current note progress isn't lost.
ContentValues values = new ContentValues();
values.put(NotePad.Notes.COLUMN_NAME_NOTE, getCurrentNoteText());
values.put(NotePad.Notes.COLUMN_NAME_TITLE, getCurrentNoteTitle());
// do this update in background on an AsyncQueryHandler or equivalent
mAsyncQueryHandler.startUpdate (
mToken, // int token to correlate calls
null, // cookie, not used here
mUri, // The URI for the note to update.
values, // The map of column names and new values to apply to them.
null, // No SELECT criteria are used.
null // No WHERE columns are used.
);
}
onDestroy()
- 进入这个阶段的原因:
- activity完成(用户取消activity,或者调用了finish()方法)
- 系统自动删除activity(手机转动,或者多窗口模式下)
- 所有生命周期组件会收到
onDestroy()
事件,这里我们可以所有需要停止的东西
3. Activity生命周期被回收的几率表
被杀的可能性 | 过程状态 | Activity状态 |
---|---|---|
最小 | 前端 | Created Started Resumed |
中等 | 后端(lost focus) | Paused |
最高 | 后端(不可见) 空 |
Stopped destroyed |
4. 保存和储存短暂的UI状态
考虑如下两种情况
- 用户转换屏幕或者切换到多窗口模式时,系统会默认摧毁之前的activity,但是用户希望能够保持原来的activity不变
- 用户有时候可能一不小心从当前app切换到其他app,系统会默认摧毁之前的activity,当然我们希望用户切换回来的时候还是保持当前的状态
解决方法: 保存UI状态:ViewModel + obSaveInstanceState()
4.1. Instance state
- 系统用于保存之前状态的过程为
Instance state
--其实是一些保存在Bundle
对象的键值对 - 系统默认使用
Bundle
的Instance state
来保存每个View的信息(比如EditText中的文本)
4.2.通过onSaveInstanceState()
保存一些轻度,简单的UI状态
- 当Activity准备停止的时候,系统就会调用
onSaveInstanceState()
来保存一些基本的信息,比如edittext中的value.. - 如果你想要保存更多的内容,需要重写
onSaveInstanceState()
方法,添加新的key-value对到Bundle
对象中 - 如果重写
onSaveInstanceState()
方法,一定调用super implmenetaion
static final String STATE_SCORE = "playerScore";
static final String STATE_LEVEL = "playerLevel";
// ...
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
// Save the user's current game state
savedInstanceState.putInt(STATE_SCORE, mCurrentScore);
savedInstanceState.putInt(STATE_LEVEL, mCurrentLevel);
// Always call the superclass so it can save the view hierarchy state
super.onSaveInstanceState(savedInstanceState);
}
4.3. 通过保存的UI状态恢复活动的UI
- 我们可以在
onCreate
和onRestoreInstanceState()
中调用Bundle
对象来恢复UIonCreate
:只有当创建一个新的activtiy实例,才会调用这个方法,必须坚持Bundle是否为空,空的话,创建新的实例,不是空的话,恢复之前的UIonRestoreInstanceState()
:这个方法在onStart()
方法之后调用,系统只会在Bundle不为空的时候调用,所以你不用检查是否为null
// method 1
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); // Always call the superclass first
// Check whether we're recreating a previously destroyed instance
if (savedInstanceState != null) {
// Restore value of members from saved state
mCurrentScore = savedInstanceState.getInt(STATE_SCORE);
mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL);
} else {
// Probably initialize members with default values for a new instance
}
// ...
}
// method2
public void onRestoreInstanceState(Bundle savedInstanceState) {
// Always call the superclass so it can restore the view hierarchy
super.onRestoreInstanceState(savedInstanceState);
// Restore state members from saved instance
mCurrentScore = savedInstanceState.getInt(STATE_SCORE);
mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL);
}
5.Activity之间是如何切换的?
5.1 从一个Activity切换到另外一个Activity:
1. startActivity()
- 如果不需要返回一个结果,就用这个
Intent intent = new Intent(this, SignInActivity.class);
startActivity(intent);
你也可以通过startActivity启动一些以后的组件来扩展功能(调用Email的app)
Intent intent = new Intent(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_EMAIL, recipientArray);
startActivity(intent);
The EXTRA_EMAIL
extra added to the intent is a string array of email addresses to which the email should be sent. When an email application responds to this intent, it reads the string array provided in the extra and places them in the "to" field of the email composition form. In this situation, the email application's activity starts and when the user is done, your activity resumes.
2.startActivityForResult()
- 当你需要从即将结束的Activity中返回一个值的时候用这个,比如你从当前activity的列表中选中一个水果,你想要保存这个选中的水果
- 当有一个子类Activity的时候,它可以调用
setResult(int)
来返回数据给他的父类Activity - 父类Activity使用
onActivityResult(int, int, Intent)
来获取信息
public class MyActivity extends Activity {
// ...
static final int PICK_CONTACT_REQUEST = 0;
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
// When the user center presses, let them pick a contact.
startActivityForResult(
new Intent(Intent.ACTION_PICK,
new Uri("content://contacts")),
PICK_CONTACT_REQUEST);
return true;
}
return false;
}
protected void onActivityResult(int requestCode, int resultCode,
Intent data) {
if (requestCode == PICK_CONTACT_REQUEST) {
if (resultCode == RESULT_OK) {
// A contact was picked. Here we will just display it
// to the user.
startActivity(new Intent(Intent.ACTION_VIEW, data));
}
}
}
}
6.Activity的几种状态
状态 | 产生原因 | 调用方法 |
---|---|---|
配置变化 | 转屏幕 更改语言 插入设备 |
原activity被销毁:onPause()->onStop()->onDestroy() 原activity被重建:onCrate()->onStart()->onResume() |
新的activity或者对话框显示 | 比如弹出一个对话框-> 导致被覆盖的activity暂停 | 新的activity半覆盖: onPause()>onResume() 新的activity全覆盖:onPause()->onStop()->onRestart()->onStart()->onResume() |
点击返回按钮 | 点击Back 按钮 |
原activity: onPause()->onStop()->onDestroy()->remove from back stack onSaveInstanceState() not work 你可以重写 onBaclPressed |
系统杀死app | 系统需要释放内存 | .... |
7.实例演示Activity的生命周期
创建两个activity: mainactivity和otheractivity
public class OtherActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_other);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
System.out.println("--OtherActivity: OnCreate--");
}
@Override
protected void onStart() {
super.onStart();
System.out.println("--OtherActivity: OnStart--");
}
@Override
protected void onResume() {
super.onResume();
System.out.println("--OtherActivity: OnResume--");
}
@Override
protected void onPause() {
super.onPause();
System.out.println("--OtherActivity: OnPause--");
}
@Override
protected void onStop() {
super.onStop();
System.out.println("--OtherActivity: OnStop--");
}
@Override
protected void onDestroy() {
super.onDestroy();
System.out.println("--OtherActivity: OnDestroy--");
}
@Override
protected void onRestart() {
super.onRestart();
System.out.println("--MainActivity: OnRestart--");
}
}
otherActivity也差不多,然后执行程序
当程序呈现第一个页面的时候,打印的信息是:
当点击按钮,进入第二个activity的时候:
当点击返回按钮返回主activity的时候:
Android Studio教程03-Activtiy生命周期的理解的更多相关文章
- Android Studio 之 Activity 的生命周期
翻转屏幕,会重新加载Activity package com.example.activitylivecycle; import android.os.Bundle; import android.u ...
- <杂记>Android Studio 3.0-3.1 汉化包 (转载)
JetBrains 系列软件汉化包 关键字: Android Studio 3.0-3.1 汉化包 CLion 2018.1 汉化包 GoLand 2017.3.2-2018.1 汉化包 Intell ...
- Android studio教程
Android studio教程: http://jingyan.baidu.com/season/44062
- iOS10 UI教程视图的生命周期
iOS10 UI教程视图的生命周期 说到视图的生命周期一般都是指视图控制器的视图生命周期.在视图的声明周期中最主要的有8个方法,分别为loadView().viewDidLoad().viewWill ...
- Android 页面跳转之生命周期调用顺序问题
Android Activity 常用技巧 Android Activity 启动模式和任务栈 Android 页面跳转之生命周期调用顺序问题 一.页面跳转逻辑分析 1.1 跳转逻辑分析 Androi ...
- Android开发工程师文集-Activity生命周期,启动方式,Intent相关介绍,Activity详细讲解
前言 大家好,给大家带来Android开发工程师文集-Activity生命周期,启动方式,Intent相关介绍,Activity详细讲解的概述,希望你们喜欢 Activity是什么 作为一个Activ ...
- vue教程2-01 vue生命周期、钩子函数
vue教程2-01 vue生命周期.钩子函数 <!DOCTYPE html> <html lang="en"> <head> <meta ...
- Android React Native组件的生命周期及回调函数
熟悉android的童鞋应该都清楚,android是有生命周期的,其很多组件也是有生命周期.今天小编和大家分享的React Native组件的生命周期,还不了解的童鞋,赶紧来围观吧 在android开 ...
- [译]线程生命周期-理解Java中的线程状态
线程生命周期-理解Java中的线程状态 在多线程编程环境下,理解线程生命周期和线程状态非常重要. 在上一篇教程中,我们已经学习了如何创建java线程:实现Runnable接口或者成为Thread的子类 ...
- 对Rust所有权、借用及生命周期的理解
Rust的内存管理中涉及所有权.借用与生命周期这三个概念,下面是个人的一点粗浅理解. 一.从内存安全的角度理解Rust中的所有权.借用.生命周期 要理解这三个概念,你首要想的是这么做的出发点是什么-- ...
随机推荐
- Winform杂项
1.控件右键属性:ContextMenuStrip,设置菜单 2.编辑代码:this.treeView1.Nodes.Remove(this.treeView1.SelectedNode);//获取树 ...
- C# Json反序列化
Json反序列化有两种方式[本人],一种是生成实体的,方便处理大量数据,复杂度稍高,一种是用匿名类写,方便读取数据,较为简单. 使用了Newtonsoft.Json,可以自行在nuget中导入 Jso ...
- 深入理解JAVA中的NIO
前言: 传统的 IO 流还是有很多缺陷的,尤其它的阻塞性加上磁盘读写本来就慢,会导致 CPU 使用效率大大降低. 所以,jdk 1.4 发布了 NIO 包,NIO 的文件读写设计颠覆了传统 IO 的设 ...
- [leetcode]984. 不含 AAA 或 BBB 的字符串
给定两个整数 A 和 B,返回任意字符串 S,要求满足: S 的长度为 A + B,且正好包含 A 个 'a' 字母与 B 个 'b' 字母: 子串 'aaa' 没有出现在 S 中: 子串 'bbb' ...
- Elastic-Job-分布式调度解决方案
Elastic-Job是一个分布式调度解决方案,由两个相互独立的子项目Elastic-Job-Lite和Elastic-Job-Cloud组成. Elastic-Job-Lite定位为轻量级无中心化解 ...
- 一个优秀的SEOer必须掌握的三大标配技术
首先,认识网页代码是基础 这里所讲的网页代码是指HTML代码,并不是指复杂的PHP模板技术.一般的培训机构总是提倡学SEO不用学网页代码,只要会购买域名空间搭建网站就行,因为现在的网站模板太丰富了,对 ...
- CSS制作镂空字体
1.效果图 2.html内容: <!doctype html><html lang="en"><head> <meta charset=& ...
- JS之表单提交时编码类型enctype详解
简介 form的enctype属性为编码方式,常用有两种:application/x-www-form-urlencoded和multipart/form-data,默认为application/x- ...
- vuejs通过filterBy,orderBy实现搜索筛选,降序排序数据实例
直接贴代码了: 先上输入前的样子: <style> #example{margin:100px auto;width:600px;} .show{margin:10px;} #search ...
- Activiti实现流程自由跳转
import org.activiti.engine.ProcessEngine; import org.activiti.engine.TaskService; import org.activit ...