Activity 提供窗口,供应在其中多个界面。此窗口通常会填满屏幕,但也可能小于屏幕并浮动在其他窗口之上。
大多数应用包含多个屏幕,这意味着它们包含多个 Activity。通常,应用中的一个 Activity 会被指定主 Activity,即用户启动应用时显示的第一个屏幕。然后,每个 Activity 都可以启动另一个活动,以执行不同的操作。
Activity提供一个能让用户操作并与之交互的界面。
AppCompatActivity 继承了 Activity 类,拥有了窗口的特性,是一个可视化界面,MainActivity是一个可视化界面正是由于它继承了 AppCompatActivity。
在清单文件中声明 Activity,添加
... ...
android:name,必需属性,用于指定Acitiviy的类名称。
该步骤在新建activity文件时会自动创建
action表示动作,就是想要做的事情的名称,给当前actitvity起别名,但不能乱起
指定当前活动的类型
指定活动能发送的类型
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
android.intent.action.MAIN -> 入口activity
Intent是 Activity、Serviece和 BroadcastReceiver三个应用组件之间进行通信的信使,它还可以携带数据。
显示意图:明确目标组件的意图
Intent(Context packageContext, Class> cls)
常用在操作当前应用的组件
隐式意图:没有明确目标组件的意图
Intent(String action)
常用在使用其他应用的组件时
- Intent intent = new Intent(ButtonActivity.this,MainActivity.class);
- startActivity(intent);
在运行时才知道能打开哪一个界面
隐式启动的两种构造方法 * public Intent(String action, Uri uri) * public Intent(String action) * action:Activity的别名 ,编译阶段无论写什么的都不会报错 * uri: Uri对象,打开的路径
- // 打开百度
- Intent intentS = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.baidu.com"));
- startActivity(intentS);
在运行前知道到底要启动哪一个界面-使用意图
Intent(Context packageContext, Class<?> cls)
跳转后返回只需要使用 finish() 结束当前activity
startActivityForResult(Intent intent,int requestCode);
跳转到第二个页面,设置请求码为1000
- Intent intent = new Intent(this,ActivityLife.class);
- // 参数2:请求码
- startActivityForResult(intent,1000);
setResult(int resultCode,Intent data) 设置要返回的结果
第二个页面返回数据:
- // 通过startActivityForResult启动activity-返回结果
- public void backRes(View view) {
- // 设置结果
- Intent intent = new Intent(); //此时intent不作为跳转使用,而是用来传递返回的数据
- intent.putExtra("返回的数据","第二个界面返回的是10000000");
- /*参数1:请求码 参数2:返回的数据*/
- setResult(RESULT_OK,intent);
- finish(); //结束当前Acticity
- }
在第一个页面调用 onActivityResult 方法处理返回的数据:
如果通过 startActivityForResult 启动了第二个activity,当第二个activity处理结束后,再回到当前activity时,一定会自动回调 onActivityResult 方法 。在 onActivityResult 方法中我们可以处理第二个activity返回的结果。(如。拍照后得到的照片,从图库中选取的图片)
- @Override
- protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
- super.onActivityResult(requestCode, resultCode, data);
- // 判断新开的activity返回的结果
- /* 当返回结果都是成功时,请求码==1000则进行操作 */
- if(resultCode == -1){
- if(requestCode == 1000){
- assert data != null;
- Log.e("ActivityWithResults","自动进入onActivityResult requestCode:"+requestCode+",resultCode:"+resultCode+",返回的数据"+data.getStringExtra("返回的数据"));
- }
- }
intent.putExtra(String name,XXX value) 保存数据
intent.getXXXExtra(String name) 获取数据
getIntent()获取携带数据的意图
A的activity(传递)
- Intent intent = new Intent(this,ActivityLife.class);
- //添加参数
- intent.putExtra("传递的String类型参数","这是上一个页面传递过来的String类型参数");
- intent.putExtra("传递的double类型参数",24.99);
- intent.putExtra("传递的int类型参数",24);
- intent.putExtra("传递的bool类型参数",false);
- startActivity(intent);
B的activity(接收)
- // 获取上一个页面传递过来的数据,获取数据时有些需要给出默认值
- Intent getIntent = getIntent();
- String dataString = getIntent.getStringExtra("传递的String类型参数");
- int dataInt = getIntent.getIntExtra("传递的int类型参数",1);
- double dataDouble = getIntent.getDoubleExtra("传递的double类型参数",2.1);
- boolean dataBool = getIntent.getBooleanExtra("传递的bool类型参数",true);
-
- TextView textView = findViewById(R.id.show);
- textView.setText("上一个页面传递是数据"+dataString+dataInt+dataDouble+dataBool);
intent.getSerializableExtra(String name) 获取序列化对象数据
新建一个Student对象类
- package com.example.androidstudiostudy.data;
-
- import java.io.Serializable;
-
- // 将对象序列化,序列化的作用
- /* 1.想把内存中的对象保存到一个文件活数据库中时
- * 2.想利用套接字Socket在网络中传递对象*/
- public class Student implements Serializable {
- private String name;
- private int age;
- private double money;
- private boolean check;
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public int getAge() {
- return age;
- }
-
- public void setAge(int age) {
- this.age = age;
- }
-
- public double getMoney() {
- return money;
- }
-
- public void setMoney(double money) {
- this.money = money;
- }
-
- public boolean isCheck() {
- return check;
- }
-
- public void setCheck(boolean check) {
- this.check = check;
- }
-
- public Student(String name, int age, double money, boolean check) {
- this.name = name;
- this.age = age;
- this.money = money;
- this.check = check;
- }
- }
A页面传递:
- // 实例化一个新建的 Student 对象
- Student student1 = new Student("沈成林",23,200000.999,true);
- // 参数1:String name - 本次数据的名称
- // 参数2:@Nullable Serializable value - 序列化数据对象
- intentC.putExtra("data_object",student1);
- startActivity(intentC);
B页面接收:
- Intent getIntent = getIntent();
- // 获取对象数据 - 强转成 Student 对象
- Student student = (Student) getIntent.getSerializableExtra("data_object");
- if (student != null) {
- TextView textView2 = findViewById(R.id.show2);
- textView2.setText("上一个页面传递是数据"+student.getName()+student.getAge()+student.getMoney()+student.isCheck());
- else {
- // 处理student对象为空的情况,比如给出一个默认值或者显示错误信息
- TextView textView2 = findViewById(R.id.show2);
- textView2.setText("上一个页面未传递有效的Student对象");
- }
何时会进入到不可操作的状态?
有另一个activity进入到了前台(本activity被部分挡住了)。此时虽然不可操作,但是部分可见的
当有一个活动A来到前台完全启动后,有一个活动B也来到前台,慢慢启动时,A就会进入到onPause()方法,暂停活动,当B完全准备好后,A就会彻底的停止,进入onStop()方法
运行-死亡:onPause() ->onStop()->onDestory()
死亡-运行:onCreate() ->onStart()->onResume()
运行-停止:onPause() ->onStop()
停止-运行:onRestart()->onStart()->onResume()
运行-暂停:onPause()
暂停-运行:onResume()
栈:后进先出
一个应用启动,系统就会为其创建一个对应的任务栈来存储并管理该应用的Activity对象。
只有栈顶的activity才会被显示。
系统中会有多个应用,同时也会有多个任务栈。
当前应用的任务栈会在我们打开其他应用或者转到主屏幕时转移到后台,在后台时,任务中的所有 activity 都会停止,但任务的返回堆栈保持不变,即当其他任务发生时,任务会失去焦点。
当它回到前台时,会从上次停下的地方继续执行。
由于返回堆栈中的 activity 绝不会重新排列,因此,应用中的一个 activity 可能会多次实例化,即使来自不同的任务也是如此,如果不想启动多次,可以管理activity的启动模式。
每一次调用startActivity()都会创建一个新的实例,不管栈内是否存在该实例,打开就会放入任务栈,返回时依次从后退栈。
在清单文件中设置启动模式:
android:launchMode="standard"
顶部是你正想要打开的activity,直接复用,不会新建实例,如果没有,则会新建实例再放入栈中。
注意,一定要在顶部,不然退栈顺序和标准模式一样
在清单文件中设置启动模式:
android:launchMode="singleTop"
从MainActivity -> MainActivity->MainActivity-> MainActivity
此时顶部就是要打开的activity,直接复用,所以只返回一次就到了主页
想打开已经打开过的 activity B,此模式会保证栈中只有一个,会弹出B之后的所有activity,保证它重回栈顶
android:launchMode="singleTask"
MainActivity ->ButtonActivity ->ConstraintActivity ->MainActivity
只返回一次就回到主页,因为此时想打开MainActivity,但栈中此时已经有了,根据栈内复用的特性它会退出MainActivity后的所有activity, ButtonActivity ->ConstraintActivity
想要打开新activity,会放在一个新的任务栈中且该Task有且只有一个activity实例,如果已经创建过该activity实例,则不会再创建新的任务栈,只会将之前的唤醒。
- <activity
- android:launchMode="singleInstance"
- android:name=".MainActivity"
- android:exported="true" >
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
MainActivity ->ButtonActivity ->ConstraintActivity ->MainActivity
返回到ButtonActivity后再返回就直接回到了主页。这是由于MainActivity在一个单独的任务栈中,在第一次返回的时候已经被撤销了。