热门标签 | HotTags
当前位置:  开发笔记 > 运维 > 正文

android初学者必须掌握的Activity状态的四大知识点(必读)

这几天一直都在捣鼓android的知识点,兴趣班的老师,讲课太过深奥,天(想到什么就见什么,后后面完全不想听),最后自己找资料总结了在And

这几天一直都在捣鼓android的知识点,兴趣班的老师,讲课太过深奥,天(想到什么就见什么,后后面完全不想听),最后自己找资料总结了在Android学习中很重要的一个组件Activity,那就开始吧!

第一:掌握Activity的四种状态及什么时候触发

首先我们要知道什么是Activity,简单来说Activity其实就是一个屏幕的显示页面。(简单的阐述)

我们知道Activity是由Activity栈进管理,当来到一个新的Activity后,此Activity将被加入到Activity栈顶,之前的Activity位于此Activity底部。

Acitivity一般意义上有四种状态:

  1、Running状态: 一个新的Activity启动入栈后,它在屏幕的最前端,处于栈的最顶端,此时它处于可见并可和用户交互的激活状态,Android试图尽最大可能保持它活动状态,杀死其它Activity来确保当前活动Activity有足够的资源可使用。当另外一个Activity被激活,这个将会被暂停。

  2、Paused状态:当Activity处于此状态时,此时它依然与窗口管理器保持连接,系统继续维护其内部状态,它仍然可见,但它已经失去了焦点,故不可与用户交互。

  3、Stopped状态: 当Activity 不可见时,Activity处于Stopped状态。当Activity处于此状态时,一定要保存当前数据和当前的UI状态,否则一旦Activity退出或关闭时,当前的数据和UI状态就丢失了

  4、Killed状态: Activity被杀掉以后或者被启动以前,处于Killed状态。这是Activity已从Activity堆栈中移除,需要重新启动才可以显示和使用。

对四种状态的一个总结:Running状态和Paused状态是可见的,Stopped状态和Killed状态时不可见的,当然Starting是有系统自身自动创建,而且每一个活动( Activity )都处于某一个状态,对于开发者来说,是无法控制其应用程序处于某一个状态的,这些均由系统来完成。

但是当一个活动的状态发生改变的时候,开发者可以通过调用 onXX() 的方法获取到相关的通知信息。

接下来讲下各种状态在何时触发:

1、Running状态:

期间触发的函数及顺序为: onCreate() ->on Start() -> onResume()。

注意:

1.1:onCreate()只有在该Activity是第一次被创建时才会被调用,主要是负责Activity的一般性的初始化设置,包括视图的创建,数据的绑定等等。

 需要注意的是若之前有冻结的state(即系统对该Activity调用过onSaveInstanceState()函数),则可以通过其 Bundle 参数进行state恢复。

1.2:on Start()是当Activity正在变为可见状态时才会被调用。一般地在此期间可以注册一个广播等等。

1.3:onResume()是在该Activity将要和用户进行交互时被调用,此时Activity位于的活动栈顶部。

2、Paused状态:

运行状态到暂停状态所触发的函数及顺序为:onResume() -> onPuased()

 暂停状态恢复至运行状态所触发的函数及顺序为:onPuased() -> onResume()。     

注意:

2.1:onPuased()是当一个Activity失去系统焦点后将会被调用,包括见面被部分遮挡,以及设备转入休眠状态等等。一般地在此期间对一些未保存的数据进行持久化并停 止其他需要耗费CPU的操作,同时不可进行耗时操作,否则会阻塞系统UI线程。

2.2:一个处于暂停状态的Activity只有在系统极度缺乏内存资源的情况下才会被系统强制结束。

3、stopped状态:

暂停状态到停止状态所触发的函数及顺序为:onPuased() -> on Stop()。

停止状态恢复至运行状态所触发的函数及顺序为:on Stop() -> onRestart() -> on Start() -> onResume()。

注意:

3.1:on Stop()是当一个Activity变为不可见时将会被调用,此时可能是由于该Activity要被注销或新的Activity完全遮挡了该Activity。在此期间一般可以进行取消注册 广播等操作,因此用户不可见。

3.2:onRestart()是当一个Activity从停止状态恢复至运行状态时将会被优先调用。

4、Killed状态:

停止状态到死亡状态分为两种情况:(1)由用户操作导致,则执行:on Stop() -> onDestroy()。

                (2)由系统自动强制执行,则该Activity被强行结束。

注意:

4.1:onDestroy()是当一个Activity正在被系统finished期间被调用的。

 第二:掌握Activity的生命周期及各个阶段触发的事件名称和触发次数

Activity一共有七个生命周期函数,分别为onCreate(),onRestart(),on Start(),onReusme(),onPause(),on Stop(),onDestory()。

1:onCreate()

当Acitivity第一次被创建时触发,一般在这里要做的事情包括创建视图(setContentView())、向视图填充必要的数据等等。

2:onRestart()

如果Activity之前被stop过,那么下一次onStart()方法之前会先触发这个方法,当处于停止状态的活动需要再次展现给用户的时候,触发该方法。

3:onStart()

只要Activity从不可见变成可见,就会触发到这个方法,但被AlertDialog遮挡/显示的情况不算在内。

 4:onResume()

当Activity来到最上层的时候,也就是开始与用户直接交互时,触发这个方法。例如本来Activity被一个AlertDialog遮挡,当这个AlertDialog消失时,onResume()方法就被触发。

5:onPause()

同onResume()的触发条件刚好相反,如果Activity本来在最上层,当它要让出最上层的位置时会触发这个方法。

onPause()和onResume()是被触发最频繁的两个方法,所以在这里不应该执行过于消耗资源的方法。

6: onStop ()

当一个活动不再需要展示给用户的时候,触发该方法。如果内存紧张,系统会直接结束这个活动,而不会触发 onStop 方法。

所以保存状态信息是应该在onPause时做,而不是onStop时做。活动如果没有在前台运行,都将被停止或者Linux管理进程为了给新的活动预留足够的存储空间而随时结束这些活动。因此对于开发者来说,在设计应用程序的时候,必须时刻牢记这一原则。在一些情况下,onPause方法或许是活动触发的最后的方法,因此开发者需要在这个时候保存需要保存的信息。

7: onDestroy ()

当活动销毁的时候,触发该方法。和onStop 方法一样,如果内存紧张,系统会直接结束这个活动而不会触发该方法。

接下来我们用代码来实现具体的方法触发:

创建一个android项目,在MainActivity中进行编辑    

public class MainActivity extends Activity {
  
  // onCreate系统自动初始化
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Log.i("--MainActivity--","--------onCreate- 系统自动初始化---------");
  }
  
  //从stop转为激活状态时执行
  @Override
  protected void onRestart() {
    super.onRestart();
    Log.i("--MainActivity--", "------onRestart--stop转为激活状态时执行----");
  }
    
  //Activity开始加载事件时执行(新创建时,或者重新启动的时候执行!)
  @Override
  protected void onStart() {
    super.onStart();
    Log.i("--MainActivity--", "--------onStart---开始加载事件时执行-----");
  }
  
  //Activity恢复到激活状态时执行(任何一次进入激活状态都将执行)
  @Override
  protected void onResume() {
    super.onResume();
    Log.i("--MainActivity--", "----------onResume-恢复到激活状态时执行-------------");
  }
  
  //Activity 被覆盖的时候执行
  @Override
  protected void onStop() {
    super.onStop();
    Log.i("--MainActivity--", "-------onStop ----被覆盖的时候执行-----------");
  }
  
  //Activity 退出或者被回收时执行,仅执行一次
  @Override
  protected void onDestroy() {
    super.onDestroy();
    Log.i("--MainActivity--","---------onDestroy---退出或者被回收时执行,仅执行一次--------------");
  }

}

当我们启动部署程序的时候,通过LogCat 日志来查看信息

以上就是关于掌握Activity的生命周期及各个阶段触发的事件名称和触发次数

 第三:掌握Activity中如何在各个窗体之间传值

如上我们知道了Activity是一个窗体的页面显示,既然是页面显示,那么我们就需要进行显示数据与读取数据,那么问题来了,Activity中如何在各个窗体之间进行传值。

这里引入一个关键字: Intent:在Android中,Intent对象负责各个Activity窗口之间的切换,同时他更担负起数据传输重任。 

接下来我们用代码来具体实现分析(采用工具Eclipse):

第一:首先我们创建一个名为ActivityValue 的Android项目 并在src 目录下分别创建名为:SecondActivity JAVA普通类 ,Second_OneActivity JAVA普通类 分别继承Activity

在目录layout 中创建分别跟SecondActivity ,Second_OneActivity  相对应的布局xml文件

名为:activity_second_one.xml
 名为:activity_second.xml
 接下来我们在SecondActivity.java 文件中进行编辑:

 package com.example.activityvalue;

import java.util.ArrayList;

import com.example.activitylife.R;
import com.example.activityvalue.Second_OneActivity;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;

public class SecondActivity extends Activity{

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    //声明Activity
    setContentView(R.layout.activity_second);
  }
  
  //传递一个普通值到一个窗体
  public void MytestOne(View view){
    System.out.println("=================传递一个普通值到一个窗体=====================");
    Intent intent = new Intent(this,Second_OneActivity.class);
    //窗体传值
    intent.putExtra("stuName","习大大");
    intent.putExtra("stuage",20);
    intent.putExtra("isMerry",false);
    //设置数组
    intent.putExtra("stuHobby",new String[]{"篮球","羽毛球","足球"});
    //设置集合数值
    ArrayList list = new ArrayList();
    list.add("北京");
    list.add("广东");
    list.add("美国");
    //设置数值到Intent 中
    intent.putStringArrayListExtra("stuCitys",list);
    //开启Activity
    startActivity(intent);
  }
  
}

我们先在SecondActivity 文件中部署好我们需要取出的数据 不同的类型数据m,由上文可知我们是通过intent 来进行传值

在Second_OneActivity 进行编辑:

package com.example.activiyvalue;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.TextView;

public class Second_OneActivity extends Activity{
  
  private TextView showText;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    
    //声明一个布局文件
    setContentView(R.layout.activity_second_one);
    
    //从Intent 中取出传递过来的数据
    Intent intent = getIntent();
    
    //取出普通数据
    String name = intent.getStringExtra("stuName");
    int age = intent.getIntExtra("stuAge", 0);
    boolean isMerry = intent.getBooleanExtra("isMerry",false);
    
    //取出数组数据
    String[] hobbys = intent.getStringArrayExtra("stuHobby");
    String hobby = Arrays.toString(hobbys);
    
    //取出ArrayList 集合数据
    ArrayList citys =intent.getStringArrayListExtra("stuCitys");
    String city = Arrays.toString(citys.toArray());
    
    //声明Activity
    showText = (TextView) findViewById(R.id.showText);
    
    //在Activity 中动态添加文本内容
    String str = "姓名:"+name+",年龄:"+age+"\n"+
           "婚否:"+isMerry+"\n"+
           "爱好:"+hobby+"\n"+
           "城市:"+city;
    showText.setText(str);  
 
}

如果在第21 行 声明一个布局文件 报错时,则说明R 文件中 没有自动生成句柄  我们可以这样做

在项目右击重新加载项目便可:

接下来我们要在项目目录下的AndroidMainifest.xml 中进行声明Activity 类文件

在声明的前提我们先进行设置好string参数

接下来在AndroidMainifest.xml 开始声明
接下来要回到MainActivity.java 定义一个方法 用来转跳Activity

 //============================打开一个窗体传值的案例==============================
   public void setValuesMyDemo(View view){
     Intent intent = new Intent(this,SecondActivityclass); //创建一个Activity对象
     //开始激活Activity状态为start
     startActivity(intent);
   }

在activity_mainxml 布局文件中定义一个Button 按钮

 

按钮绑定一个方法对应的是MainActivity.java 中的 setValuesMyDemo 方法

setValuesMyDemo 方法中调用 下一个Activity  也就是SecondActivity.java 对应的布局文件

那么我们就要在SecondActivity.java 对应的布局文件activity_second.xml 中添加一个button

activity_second.xml 中点击事件绑定的方法是SecondActivity.java 文件中对应的MytestOne方法:
在MytestOne方法中 调用了下一个Activity 也就是Second_OneActivity.java   我们在这个文件中进行读取数据 在SecondActivity.java文件中进行设置数值

接下来见证奇迹的时刻:我们运行我们的程序,打开我们的模拟器或者真机部署文件
点击窗体中的button 进入SecondActivity的布局文件了  (此时就进行了页面的跳转)
在SecondActivity页面我们是进行了设置数值 因此 当再次点击的时候我们在Second_OneActivity 的布局文件就要进行读取数据
点击 显示跳转如下:

总结: 由上图案例可知,Activity与Activity 之间的跳转 跟 Activity与Activity 之间的传值  是通过上一个Activity对下一个Activity的调用,其中intent 对象 起到的方法很重要,起着跳转跟传值的任务!

 第三: 掌握Activity窗体状态保存问题

在这里如何保存当前的窗体状态我们通过代码来实现: 

在我们上面的案例基础上,到MainActivity.java 文件中 重写Activity 的两个方法:

onRestoreInstanceState(Bundle savedInstanceState)

//========================窗体状态保存与恢复====================================
    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
      super.onRestoreInstanceState(savedInstanceState);
      //恢复状态
      if(savedInstanceState!=null){
        String msg = savedInstanceState.getString("message");
        //设置这个数据到需要的地方
        Toast.makeText(this, "以前的消息:"+msg, 50000).show();
      }
    }

onSaveInstanceState(Bundle outState)

//========================保存的状态====================================
    @Override
    protected void onSaveInstanceState(Bundle outState) {
      // TODO Auto-generated method stub
      super.onSaveInstanceState(outState);
      //保存数据
      outState.putString("message", "Hello!");
      Toast.makeText(this, "状态已经保存!", 3000).show();
    }

完毕之后,我们开始运行程序最终结果如下:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。


推荐阅读
  • 本文介绍了在Ubuntu 11.10 x64环境下安装Android开发环境的步骤,并提供了解决常见问题的方法。其中包括安装Eclipse的ADT插件、解决缺少GEF插件的问题以及解决无法找到'userdata.img'文件的问题。此外,还提供了相关插件和系统镜像的下载链接。 ... [详细]
  • eclipse学习(第三章:ssh中的Hibernate)——11.Hibernate的缓存(2级缓存,get和load)
    本文介绍了eclipse学习中的第三章内容,主要讲解了ssh中的Hibernate的缓存,包括2级缓存和get方法、load方法的区别。文章还涉及了项目实践和相关知识点的讲解。 ... [详细]
  • 本文详细介绍了Linux中进程控制块PCBtask_struct结构体的结构和作用,包括进程状态、进程号、待处理信号、进程地址空间、调度标志、锁深度、基本时间片、调度策略以及内存管理信息等方面的内容。阅读本文可以更加深入地了解Linux进程管理的原理和机制。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • Java验证码——kaptcha的使用配置及样式
    本文介绍了如何使用kaptcha库来实现Java验证码的配置和样式设置,包括pom.xml的依赖配置和web.xml中servlet的配置。 ... [详细]
  • Android系统移植与调试之如何修改Android设备状态条上音量加减键在横竖屏切换的时候的显示于隐藏
    本文介绍了如何修改Android设备状态条上音量加减键在横竖屏切换时的显示与隐藏。通过修改系统文件system_bar.xml实现了该功能,并分享了解决思路和经验。 ... [详细]
  • 本文介绍了Android 7的学习笔记总结,包括最新的移动架构视频、大厂安卓面试真题和项目实战源码讲义。同时还分享了开源的完整内容,并提醒读者在使用FileProvider适配时要注意不同模块的AndroidManfiest.xml中配置的xml文件名必须不同,否则会出现问题。 ... [详细]
  • Android源码深入理解JNI技术的概述和应用
    本文介绍了Android源码中的JNI技术,包括概述和应用。JNI是Java Native Interface的缩写,是一种技术,可以实现Java程序调用Native语言写的函数,以及Native程序调用Java层的函数。在Android平台上,JNI充当了连接Java世界和Native世界的桥梁。本文通过分析Android源码中的相关文件和位置,深入探讨了JNI技术在Android开发中的重要性和应用场景。 ... [详细]
  • Android开发实现的计时器功能示例
    本文分享了Android开发实现的计时器功能示例,包括效果图、布局和按钮的使用。通过使用Chronometer控件,可以实现计时器功能。该示例适用于Android平台,供开发者参考。 ... [详细]
  • Activiti7流程定义开发笔记
    本文介绍了Activiti7流程定义的开发笔记,包括流程定义的概念、使用activiti-explorer和activiti-eclipse-designer进行建模的方式,以及生成流程图的方法。还介绍了流程定义部署的概念和步骤,包括将bpmn和png文件添加部署到activiti数据库中的方法,以及使用ZIP包进行部署的方式。同时还提到了activiti.cfg.xml文件的作用。 ... [详细]
  • Hibernate延迟加载深入分析-集合属性的延迟加载策略
    本文深入分析了Hibernate延迟加载的机制,特别是集合属性的延迟加载策略。通过延迟加载,可以降低系统的内存开销,提高Hibernate的运行性能。对于集合属性,推荐使用延迟加载策略,即在系统需要使用集合属性时才从数据库装载关联的数据,避免一次加载所有集合属性导致性能下降。 ... [详细]
  • 项目运行环境配置及可行性分析
    本文介绍了项目运行环境配置的要求,包括Jdk1.8、Tomcat7.0、Mysql、HBuilderX等工具的使用。同时对项目的技术可行性、操作可行性、经济可行性、时间可行性和法律可行性进行了分析。通过对数据库的设计和功能模块的设计,确保系统的完整性和安全性。在系统登录、系统功能模块、管理员功能模块等方面进行了详细的介绍和展示。最后提供了JAVA毕设帮助、指导、源码分享和调试部署的服务。 ... [详细]
  • 本文介绍了常用的编辑器快捷键,包括快速转换编辑器、浏览选项卡、提取本地变量和方法、编辑器窗口最大化等功能。通过使用这些快捷键,可以提高编辑器的使用效率,减少复杂度,并提升代码的可测试性。 ... [详细]
  • Struts2+Sring+Hibernate简单配置
    2019独角兽企业重金招聘Python工程师标准Struts2SpringHibernate搭建全解!Struts2SpringHibernate是J2EE的最 ... [详细]
  • 初探PLC 的ST 语言转换成C++ 的方法
    自动控制软件绕不开ST(StructureText)语言。它是IEC61131-3标准中唯一的一个高级语言。目前,大多数PLC产品支持ST ... [详细]
author-avatar
专业长膘
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有