作为Android的四大组件之一,活动最先走进我们的视野,其重要性不言而喻,今天就抽出时间来专门对Android活动一探究竟。

什么是活动

活动即Activity,是一种可以包含用户界面的组件,Android系统中所有我们能看到的内容都在活动里,它主要用于和用户进行交互。一个应用程序可以包含零个或多个活动,活动与活动之间可以通过Intent来相互联系,当一个应用程序中至少有一个活动时,那么就一定存在一个主活动,它就是我们刚打开应用程序时所进入到的那个界面,可以在AndroidManifest.xml中进行设置。

创建活动的步骤

1.新建一个活动类,继承自Activity。

2.重写onCreate方法,并在其中通过setContentView()来加载布局文件。

- 布局文件在app/src/main/res/layout中,文件后缀为.xml。

- 如果要在xml文件中定义一个id,则使用@+id/id_name语法;如果要在xml文件中引用一个id,则使用@id/id_name语法。

3.活动注册,所有活动必须在AndroidManifest.xml中注册,给主活动指定的label不仅会成为标题栏中的内容,还会成为启动器(Launcher)中应用程序显示的名称。在标签的内部我们加入了标签,并在这个标签里添加了

这两句声明,这样这个活动将成为主活动,在点击桌面应用程序的时候首先打开的就是这个活动。如果程序中没有声明任何主活动,程序仍然正常安装,但是无法再启动器中看到或者打开该程序。

隐藏标题栏

有时为了全屏显示活动或者显示开发者自定义的标题栏,需要在活动中不显示标题栏,这时需要如下代码

requestWindowFeature(Window.FEATURE_NO_TITLE)

这句代码一定要在setContentView()之前执行,不然会报错。

在活动中使用Toast

Toast译为吐司,是一种简单灵活的提醒方式,可以把一些短小的消息通知给用户,并在一段时间后消失,并且不会占据任何屏幕空间。

Toast.makeText(KUActivity.this,"在线功能稍后上线,敬请期待!", Toast.LENGTH_LONG).show();

其中,第一个参数Context,第二个参数要提示的内容,第三个参数为显示Toast的时间长短,其中LENGTH_LONG(长)和LENGTH_SHORT(短),记得别忘了调用show()方法来将Toast显示出来。

在活动中使用Menu

1.在res中新建menu文件夹:res-->new-->Directory,输入文件名menu,然后就可以在menu文件夹下新建菜单文件了,后缀为.xml。

2.菜单文件内容格式参考如下:

xmlns:app="http://schemas.android.com/apk/res-auto">

android:id="@+id/menu_refresh"

app:showAsAction="always"

android:title="@string/refresh"/>

3.在活动中重写onCreateOptionsMenu()方法。

public boolean onCreateOptionsMenu(Menu menu) {

getMenuInflater().inflate(R.menu.menu, menu);//给当前活动创建菜单,inflate方法第一个参数通过哪个资源文件来创建菜单,第二个参数指定我们的菜单项将添加到哪一个Menu对象中

return true;//允许创建的菜单显示出来

}

4.响应菜单事件:重写onOptionsItemSelected()方法。

public boolean onOptionsItemSelected(MenuItem item) {

switch(item.getItemId())

{

case R.id.menu_refresh:

{

//如果该菜单项被选中,则在此执行业务逻辑

}

break;

case ....

}

注:标题栏的右侧有个三点符号,这个就是菜单按钮,点击该按钮们就能看到所有的菜单项了,当点击某菜单项时,会回调到onOptionsItemSelectd()方法中。

销毁活动

Activity中提供了一个finish()方法,在活动中调用该方法即可销毁当前活动。

Intent启动活动

Intent是android程序中各个组件之间进行交互的重要方式,它不仅可以指明当前组件想要执行的动作,还可以在不同组件之间传递数据。Intent一般可被用于启动活动、启动服务以及发送广播等场景。Intent一般分为显式Intent和隐式Intent。

显式Intent

(1)Intent有多个构造方法,其中最常接触的是

Intent(Context packageContext, Class>cls)

这个构造函数接收两个参数,第一个参数Context要求提供一个启动活动的上下文Context,第二个参数Class则是指定想要启动的目标活动。

(2)Activity类中提供了一个startActivity()方法,这个方法是专门用于启动活动的,它接收一个Intent参数。

(3)显式Intent的示例如下:

Intent intent = new Intent(FirstActivity.this,SecondActivity.class);//在FirstActivity上启动SecondActivity

intent.putExtra("path",path);//把路径path保存到“path”中,传递给SecondActivity

startActivity(intent);//启动活动SecondActivity

隐式Intent

隐式Intent并不明确指出我们想要启动哪一个活动,而是指定了一系列更为抽象的action(动作)和category(种类)等信息。只有的下的和中的内容能够同时匹配上Intent中指定的action和category时,这个活动才能响应该Intent。

android.intent.category.DEFAULT是一种默认的category,在调用startActivity()方法的时候会自动将这个category添加到Intent中。每个Intent中只能指定一个action,但却能指定多个category。

隐式Intent的用法示例:

(1)在FirstActivity的中添加action和category。

android:name=".FirstActivity">

(2)在SecondActivity活动中,指定要启动的action和category。

locatVideoBtn.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

Intent intent = new

Intent("com.example.activitytest.ACTION_START");

intent.add("com.example.activitytest.MY_CATEGORY");

startActivity(intent);

}

});//由于FirstActivity的action和category能和SecondActivity中Intent中指定的一样,因此即可在SecondActivity中启动FirstActivity

(3)使用隐式Intent,我们不仅可以启动自己程序内的活动,还可以启动其他程序的活动,这使得Android多个应用程序之间的功能共享成为了可能。例如,如果我想在应用程序中展示一个百度网页,则只需要调用系统的浏览器来打开网页即可:

Btn1.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

Intent intent = new Intent(Intent.ACTION_VIEW);//Android系统内置动作

intent.setData(Uri.parse("http://www.baidu.com"));//将网址解析成一个Uri对象并将其传递到Intent中

startActivity(intent);

}

});

Intent传递数据

向下一个活动传递数据

Intent中提供了一系列putExtra()方法的重载,可以把我们想要传递的数据暂存在Intent中,启动了另一个活动后,只需要把这些数据再从Intent中取出就可以了。

(1)在启动下一个活动时存储数据

Btn.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

String data = "hello";

Intent intent = new Intent(FirstActivity.this,SecondActivity.class);

intent.putExtra("extra_data",data);

startActivity(intent);

}

});

(2)在下一个活动中取出数据

public class SecondActivity extends AppCompatActivity {

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_second);

Intent intent = getIntent();

String data = intent.getStringExtra("extra_data");//取出数据

Log.d("SecondActivity",data);

}

返回数据给上一个活动

Activity中还有一个startActivityForResult(intent, 1)方法也是用于启动活动的,但这个方法期望在活动销毁的时候能够返回一个结果给上一个活动。请求码只要是一个唯一值就可以了,这里传入了1。

(1)在FirstActivity中使用startActivityForResult()方法来启动SecondActivity。

Btn1.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

Intent intent = new Intent(FirstActivity.this,SecondActivity.class);

startActivityForResult(intent,1);

}

});

(2)在SecondActivity中通过Intent将要返回给FirstActivity的数据保存起来。

Btn2.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

Intent intent = new Intent();

intent.putExtra("return_data",“hello FirstActivity”);

setResult(RESULT_OK,intent);

finish();//销毁当前活动SecondActivity

}

});

setResult()方法专门用于向上一个活动返回数据,它接收两个参数,第一个参数用于向上一个活动返回处理结果,一般只使用RESULT_OK或RESULT_CANCELED这两个值,第二个参数则是把带有数据的Intent传递回去。

(3)当SecondActivity被销毁之后会回调上一个活动的onActivityResult(),因此在FirstActivity中重写该方法。

@Override

protceted void onActivityResult(int requestCode,int

resultCode,Intent data){

switch(requestCode){

case 1:

if(resultCode==RESULT_OK){

String resultData = data.getStringExtra("return_data");

Log.d("FirstActivity",resultData);

}

}

}

(4)如果用户在SecondActivity中没有通过点击按钮而是通过Back键返回到了FirstActivity,则我们可以通过重写onBackPressed()方法来解决这个问题,即将返回数据的代码放在此方法中即可。

@Override

public void onBackPressed() {

Intent intent = new Intent();

intent.putExtra("return_data",“hello FirstActivity”);

setResult(RESULT_OK,intent);

finish();//销毁当前活动SecondActivity

}

活动的生命周期

在了解活动的生命周期之前,我们还需要再弄清楚两部分概念:返回栈和活动的状态。

返回栈

Android是使用任务(Task)来管理活动的,一个任务就是一组存放在栈里的活动Activity的集合,这个栈也被称作返回栈(BackStack)。在返回栈中,活动是按照后进先出的规则进出栈的,每当我们按下Back键或调用finish()方法去销毁一个活动时,处于栈顶的活动会出栈。

后进先出.png

从上图可看出,当从Activity1中启动Activity2时,Activity1被推到栈底,Activity2变成栈顶,同理,Activity3进栈的过程和Activity2是一样的,如果我们按back按钮,则Activity3被弹出,Activity2则被推到栈顶,以此类推。当一直按back,返回到主页面,则所有的activity被全部弹出,则task不复存在。

Two tasks.png

其实,task有两种状态:Foreground前景和Background背景。当处于Background时,所有的activity都是停止的,当处于Foreground时,则其栈顶的Activity可与用户进行交互。因此Android是一个多任务的系统,不同任务是可以被互相切换的。

活动状态

每个活动在其生命周期中最多可能会有四种状态:

1)运行状态:当一个活动位于返回栈的栈顶时,活动处于运行状态

暂停状态:当一个活动不再处于栈顶位置,但仍然可见时,这时活动就进入了暂停状态,处于暂停状态的活动仍然是完全存活着的

停止状态:当一个活动不再处于栈顶位置,并且完全不可见的时候,就进入了停止状态。

销毁状态:当一个活动从返回栈中移除后就变成了销毁状态

活动的生存期

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

可见生存期:活动在onStart()方法和onStop()方法之间所经历的,就是可见生存期。在可见生存期内,活动对于用户总是可见的,即便有可能无法和用户进行交互

前台生存期:活动在onResume()方法和onPause()方法之间所经历的,就是前台生存期。在前台生存期内,活动总是处于运行状态的,此时的活动是可以和用户进行相互的

活动的生命周期

活动的生命周期.png

活动被回收前保存临时数据

试想,活动A启动了活动B,假设活动B全部覆盖了活动A,此时的活动A处于停止状态,若此时系统内存不足将活动A回收了,那么当我们按Back键回到活动A时,此时活动A肯定是要执行onCreate的方法的,这也就意味着之前活动A的数据肯定已经找不到了,那么如何来解决这个问题呢?

其实,Activity中还提供了一个onSaveInstanceState()回调方法,这个方法会保证一定在活动被回收之前调用,因此我们可以通过这个方法来解决活动被回收时临时数据得不到保存到的问题。

(1)通过onSaveInstanceState(Bundle outState)的Bundle参数保存临时数据。

@Override

protected void onSaveInstanceState(Bundle outState) {

super.onSaveInstanceState(outState)

String tempData = "something";

outState.putString("data_key",tempData);

}

(2)在onCreate(Bundle saveInstanceState)方法中,将数据从Bundle参数中取出。

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

if(saveInstanceState != null){

String tempData = savedInstanceState.getString("data_key");

Log.d("MainActivity",tempData);

}

}

(3) Intent还可以结合Bundle一起用于传递数据的,首先可以把需要传递的数据都保存在Bundle对象中,然后再将Bundle对象存放在Intent里。到了目标活动之后先从Intent中取出Bundle,再从Bundle中一一取出数据。

活动的启动模式

活动的启动模式一共有四种,分别是standard、singleTop、singleTask、singleInstance,可以在AndroidManifest.xml中通过标签android:launchMode属性来选择启动模式。

standard

活动默认的启动模式,在该模式下,每当启动一个新的活动,它就会在返回栈中入栈,并处于栈顶的位置。对于使用standard模式的活动,系统不会在乎这个活动是否已经在返回栈中存在,每次启动都会创建该活动的一个新的实例。

standard.png

singleTop

在该模式下,在启动活动时如果返回栈的栈顶已经是该活动,则认为可以直接使用它,不会再创建新的活动实例,但如果发现栈顶不是该活动,则创建该活动的新的实例,因此在返回栈中可能会存在该活动的多个实例。

singleTop.png

singleTask

每次启动该活动时系统首先会在返回栈中检查是否存在该活动的实例,如果发现已经存在则直接使用该实例,并把在这个活动之上的所有活动统统出栈,如果没有发现就会创建一个新的活动实例,因此在返回栈中只会存在该活动的一个实例。

singleTask.png

singleInstance

指定为singleInstance模式的活动会启用一个新的返回栈来管理这个活动(其实如果singleTask模式指定了不同的taskAffinity,也会启动一个新的返回栈),这样做就解决了共享活动实例的问题,因为不管是哪个应用程序来访问这个活动,都共用的是同一个返回栈。

singleInstance.png

List的一点小疑惑

我们在活动中会经常看到这句代码List list = new ArrayList()?

List是一个接口,而ListArray是一个类,ListArray继承并实现了List。所以List不能被构造,但可以向上面那样为List创建一个引用,而ListArray则可以被构造。

那为什么不是List list = new ArrayList()?

因为List有多个实现类,可能现在我们用的是ArrayList,也许哪一天就需要换成其它的实现类,如LinkedList或者Vector等等,因此生成List引用会更好一点。

知晓当前在哪个活动

新建一个BaseActivity extends AppCompatActivity,但不需要在AndroidManifest.xml中注册,让其成为所有活动的父类

public class BaseActivity extends AppCompatActivity {

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

Log.d("BaseActivity",getClass().getSimpleNmae());//获取当前实例的类名,并通过Log打印了出来

}

随时随地退出程序

新建一个ActivityCollector类做为活动管理器,在其中通过一个List来暂存活动,然后提供了一个addActivity()方法用于向List中添加一个活动,提供了一个removeActivity()方法用于从List中移除活动,最后提供了一个finishAll()方法用于将List中存储的活动全部都销毁掉,无论在哪个地方想退出程序,只需要调用ActivityCollector.finishAll()方法就可以了。

活动的最佳启动方法

在一个团队完成一项工程时,为了方便队友启动我们编写的活动界面,可以在我们编写的活动中新添加一个actionStart()方法,这样队友通过该方法就知道启动该活动所需要的参数类型,从而很方便地在他的活动界面启动我们编写的活动。如需要在FirstActivity中启动SecondActivity,则代码如下

在SecondActivity中添加了一个actionStart()方法

publicstatic void actionStart(Context context, String data1,

String data2) {

Intentintent = new Intent(context, SecondActivity.class);

intent.putExtra("param1",data1);

intent.putExtra("param2",data2);

context.startActivity(intent);

}

在FristActivity中调用该方法启动SecondActivity

SecondActivity.actionStart(FirstActivity.this,"data1", "data2");

android有多个活动,Android活动一探究竟相关推荐

  1. 初识Android四大组件之一Activity(活动)

    首先,这是自己学习Android开发1年以来第一次写博客,之前看了很多大佬的技术文章,发现他们也都是从基础开始总结学习的,能及时总结所学知识是一个很好的习惯.温故而知新,可以为师矣.所以,我也寻思着能 ...

  2. Android:日常学习笔记(6)——探究活动(3)

    Android:日常学习笔记(6)--探究活动(3) 活动的生命周期 返回栈 Android中的活动是可以叠加的,我们每启动一个新活动,就会覆盖在原来的活动上,点击Back以后销毁最上面的活动,下面的 ...

  3. Android 四大组件 —— 活动(活动的隐式跳转)

    上一篇我们讨论了活动的显示跳转,现在来学习活动的隐式跳转 相比于显式Intent,隐式Intent 则含蓄了许多,它并不明确指出我们想要启动哪一个活动,而是指定了一系列更为抽象的action 和cat ...

  4. 在android studio中如何创建一个类来继承另外一个类_在Android使用Transition API检测用户活动...

    在当今世界,移动设备是我们日常生活中必不可少的一部分,我们在走路.跑步.开车以及其他许多活动时都会使用移动设备. 了解用户拿着手机的时候在做什么,可以让你的应用程序根据用户的动作进行直观的调整.对于某 ...

  5. android layout引入活动,Android 开发入门-活动的基本用法

    2.1 活动是什么 活动(Activity)是一种可以包含用户界面的组件,主要用于和用户进行交互. 2.2 活动的基本用法 2.2.1 手动创建活动 右击 app/src/main/java/com/ ...

  6. 如何在Android 10中从后台启动活动

    如何在Android 10中从后台启动活动? https://www.it1352.com/1922748.html 小米手机"后台弹出界面(允许应用在后台弹出界面)"权限问题解决 ...

  7. 三星Android手机助力泰姆凯迪幼儿活动

    三星Android手机助力泰姆凯迪幼儿活动 太阳火神的美丽人生 (http://blog.csdn.net/opengl_es) 本文遵循"署名-非商业用途-保持一致"创作公用协议 ...

  8. Android 活动与活动间数据传递

    实验内容 综合运用基本组件完成一个注册与登录的应用程序设计.要求基于基础控件,综合使用Intent实现Android的Activity之间信息交换.系统包含启动页.注册页.登录页3个页面,具体要求如下 ...

  9. Android 活动与活动间数据传递--登录注册页面

    AndroidManifest.xml: <?xml version="1.0" encoding="utf-8"?> <manifest x ...

最新文章

  1. SVG.js 笔记 (一)
  2. windows解压tar.gz文件 7z
  3. shell脚本中echo显示内容带颜色
  4. linux 开机启动 自启动 设置
  5. Kafka Log Compaction 解析
  6. Java 找平方数之和的奇数
  7. 哈工大计算机学院庞,奋斗在知足与知不足之间――我与我的导师计算机学院马培军教授二三事...
  8. 算法—递归实现 C(m,n)
  9. (8)UART发送verilog与Systemverilog编码
  10. ad中电容用什么封装_【AD封装】VH3.96mm插件座子(带3D)
  11. 【html】表格table与表单form
  12. 设计一款内容阅读app,要求与市面上的产品有差异化,列举其核心功能,画出页面设计原型图(2-3个),说明其产品价值
  13. iOS小知识:nib本地化、图片本地化字符串本地化(APP 内的本地化切换)
  14. 解决There is no getter for property named ‘organization_id‘ in的报错
  15. Day 5:自己编写的mysql类
  16. 外接硬盘无法进入PE界面
  17. Oracle 中 将多行列值按照顺序合并成单值输出(connect by)
  18. 计算机配置中什么表示硬盘,电脑硬盘的分类介绍 硬盘中的Master和Slave代表什么意思...
  19. 【decode()】
  20. C++语言递归实现求从n个数中选k个进行组合的组合数

热门文章

  1. 02-走马灯 动画实现图片无缝展示
  2. Java 中的Date(获取一天的开始时间和结束时间)
  3. excel中如何冻结前三行或者其他行
  4. 昨日种种死 今日种种生
  5. Python面向对象06/反射/双下方法
  6. t.cn新浪短链接 生成
  7. RSA-详解dp泄漏
  8. 一个汉字占用多少个字节?不同的编码方式
  9. 1、4表格细线边框合并
  10. HIOKI日置RM3545电阻计/电阻表