Android中有四大组件,分别是Activity、Service、ContentProvide和BroadcastReceiver。其中Activity是负责与用户交互的组件。
一、Activity的生命周期
1、生命周期状态
Activity生命周期指的是Activity从创建到销毁的整个过程。这个过程可分为5种状态,分别是启动状态、运行状态、暂停状态、停止状态和销毁状态。
启动状态:Activity启动状态很短暂,一般情况下Activity启动后便会进入运行状态。
运行状态:Activity在此状态时处于界面的最前端,是可见的、有焦点的、可交互的。
暂停状态:Activity在此状态时,对用户仍然可见,但它无法获得焦点,对用户的操作没有响应。(不可交互)例如,当Activity上覆盖了一个透明页面或者非全屏的界面时,被覆盖的Activity就处于暂停状态。
停止状态:当Activity完全不可见时,它就处于停止状态。
销毁状态:当Activity处于销毁状态时,将被清理出内存。
2、生命周期方法
Activity的生命周期包括创建、可见、获取焦点、失去焦点、不可见、重新可见、销毁等环节。针对每个环节Activity都定义了相应的回调方法,Activity中的回调方法具体如下:
onCreate():创建Activity时调用,通常做一些初始化设计。
onStart():Activity即将可见时调用。
onResume():Activity获取焦点时调用。
onPause():当前Activity被其他Activity覆盖或屏幕锁屏时调用。
onStop():Activity对用户不可见时调用。
onRestart():Activity从停止状态到再次启动状态时调用。
onDestroy():销毁Activity时调用。
Activity生命周期模型
二、Activity的创建、配置、启动和关闭
1、Activity的创建
方式一:
在idea2023.2.5中已创建的Android项目的java目录对应包下右击选择如下内容
创建完成:
方式二:
可以自己在对应目录下新建各个文件。
2、配置Activity
创建的每一个Activity都必须在清单文件AndroidManifest.xml文件中配置才能生效,打开AndroidManifest.xml文件在<application></application>中写入如下代码:
<activity android:name=".ThirdActivity"/>
注意,如果创建时采用的方式一则无需再进行配置,AndroidManifest.xml中会自动帮忙配置好。
3、启动Activity
在MainActivity中启动SecondActivity的函数为:public void startActivity(Intent Intent),可以绑定在按钮上实现点击按钮跳转页面的功能,示例如下:
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent=new Intent(MainActivity.this,SecondActivity.class);
startActivity(intent);
}
});
4,关闭Activity
若想关闭当前的Activity,可以调用Activity提供的finish()方法,可以绑定在按钮上实现点击关闭当前页面的功能,示例如下:
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
finish();
}
});
三、Intent与IntentFilter
Intent是意图,是各组件进行交互的一种重要方式,它可以指定当前组件要执行的动作,还可以在不同组件中进行数据传递。
1、显式Intent
显式Intent指直接指定目标组件。如,使用显示Intent指定要跳转的目标Activity,示例代码如下:
Intent intent=new Intent(this,SecondActivity.class);
startActivity(intent);
创建的Intent对象中传入了2个参数,其中第一个参数this表示当前的Activity,第二个参数SecondActivity表示要跳转到的目标。
2、隐式Intent
隐式Intent不会明确指出需要激活的目标组件,它被广泛地应用在不同应用程序之间,进行消息传递。隐式Intent通过IntentFilter匹配相应的组件,匹配的属性主要有3个,分别是action、data和category属性。
tips:感觉就像一个过滤器,只要有Activity满足了匹配规矩就会响应,而不是指定某一个具体的。
它们的匹配规则如下:
action:指定Intent对象的动作,一个<intent-filter>可以有多个action属性,只要声明的Intent携带的action属性与其中一个Activity中<intent-filter>标签的action相同,action属性就匹配成功。
data:指定数据的Uri或者数据MIME类型。只要声明的Intent携带的data属性与IntentFilter中任意一个data属性相同,data就匹配成功。
category:用于为action属性添加额外信息。只有IntentFilter中罗列的category属性数量包含隐式Intent携带的category属性时,category才匹配成功。
例:使用隐式Intent实现页面跳转。
<activity android:name=".Secondsctivity">
<intent-filter>
<action android:namne="com.example.activitytest.ACTION START"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
btn_back.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent (" com. example. activitytest .ACTION_START");
StartActivity(intent);
}
});
TIPS:一个IntentFilter(Activity)可以不声明,也可以声明。但系统会默认为Intent添加category属性的name,其值为“android.intent.category.DEFAULT”,因此,为了能接收到隐式的Intent,必须在<intent-filter>中添加<category android:name="android.intent.category.DEFAUKT"/>,将被开启的Activity的category属性设置为对应值。
四、Activity之间的跳转
1、Activity之间的数据传递
(1)使用Intent的putExtra()方法传递
示例:在从MainActivity跳转到SecondActivity时,通过Intent传递数据信息。
//MainActivity.java中写入
Intent intent=new Intent();
intent.setClass(MainActivity.this,SecondActivity.class);
intent.putExtra("name","张三");
intent.putExtra("age",20);
intent.putExtra("man",true);
startActivity(intent);
//SecondActivity.java中获取(另外一个.java文件)
Intent intent=getIntent();
String name=intent.getStringExtra("name");
int age=intent.getIntExtra("age",0);
boolean isPassed=intent.getBooleanExtra("man",true);
(2)使用Bundle类传递数据
示例:在从MainActivity跳转到SecondActivity时,通过Intent传递数据信息。
//MainActivity.java中写入
Intent intent=new Intent();
intent.setClass(this,SecondActivity.class);
Bundle bundle=new Bundle();
bundle.putString("name","张三");
bundle.putInt("age",12);
bundle.putBoolean("man",true);
startActivity(intent);
//SecondActivity.java中获取
Bundle bundle=getIntent().getExtras();
String name=bundle.getString("name");
int age=bundle.getInt("age");
boolean man=bundle.getBoolean("man");
2、Activity之间数据的回传
(1)startActivityForResult()方法
startActivityForResult()方法用于开启一个Activity,当开启的Activity被销毁时,会从销毁的Activity中返回数据。startActivityForResult()方法的语法格式如下:
startActivityForResult(Intent intent,int requestCode)
在上述语法格式中,startActivityForResult()方法传递了两个参数,其中第一个表示意图对象,第二个表示请求码,用于标识请求来源。如果MainActivity的2个按钮点击事件都需跳转到SecondActivity,则可以使用请求码判断是从哪个按钮的点击事件中跳转过来的。
(2)setResult()方法
setResult()方法用于携带数据进行回传,该方法的语法格式如下:
setResult(int resultCode,Intent intent)
在上述语法格式中,setResult()方法传递了两个参数,第一个参数resultCode表示返回码,用于标识返回的数据来自哪一个Activity,第二个参数intent用于携带数据并回传到上一个界面。
(3)onActivityResult()方法
onActivityResult()方法用于接收回传数据,该方法的语法格式如下:
onActivityResult(int requestCode,int resultCode,Intent data)
在上述语法格式中,onActivityResult()方法传递了三个参数,第一个参数表示请求码,第二个表示传回码,第三个参数表示传回的数据。
(4)单独的跳转示例
i.在MainActivity的Button1控件的点击事件中,添加跳转SecondActivity的环节
btn1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//跳转SecondActivity
Intent intent=new Intent(MainActivity.this,SecondActivity.class);
startActivityForResult(intent,1);
}
});
ii.在SecondActivity的Button2控件的点击事件中,将需要回传的数据封装到Intent对象中
btn_back.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent=new intent();
intent.putExtra("data","hello");
setResult(2,intent);
finish();
}
});
setResult()方法只负责返回数据,无法实现跳转,故需用finish()方法关闭SecondActivity。
iii.在MainActivity中重写onActivityResult()方法,实现回传数据接收
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode==1&&resultCode==2){
String needData=data.getStringExtra("data");//获取回传数据
Toast.makeText(MainActivity.this,needData,Toast.LENGTH_SHORT).show();
}
}
五、实战演练
1、实战题目
编写程序,用户在第一个Activity中输入他们的身高和体重。当用户单击“计算BMI”按钮时,将数据传递到另一个Activity中,并在第二个Activity中计算BMI值并显示。当用户在第二个Activity中单击“返回”按钮时,返回到第一个Activity并将BMI指数带回第一个Activity显示。
2、实战源码
MainActivity.java
public class MainActivity extends AppCompatActivity {
private Button btn_BMI;
private TextView tv_bmi;//存放返回的BMI的值
private double bmi;//存放返回的BMI的值
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout1);
init();
}
private void init(){
btn_BMI=findViewById(R.id.btn_BMI);//找到layout1页面中的“计算BMI”按钮
tv_bmi=findViewById(R.id.tv_bmiVlues);
EditText et_height=findViewById(R.id.et_height);
EditText et_weight=findViewById(R.id.et_weight);
btn_BMI.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//跳转SecondActivity
Intent intent=new Intent();
intent.setClass(MainActivity.this,SecondActivity.class);
String height=et_height.getText().toString();
String weight=et_weight.getText().toString();
intent.putExtra("height",height);
intent.putExtra("weight",weight);
startActivityForResult(intent,1);
}
});
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode==1&&resultCode==2){
bmi=data.getDoubleExtra("bmi",0);//获取回传数据
tv_bmi.setText("BMI已计算完成,您的BMI值为:"+bmi);
}
}
}
SecondActivity.java
public class SecondActivity extends AppCompatActivity {
private Button btn_back;
private double height;//身高
private double weight=0;//体重
private double bmi=0;//BMI
private TextView tv_bmi;//存放返回的BMI的值
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout2);
init();
}
private void returnData(){
Intent intent=new Intent();
intent.putExtra("bmi",bmi);
setResult(2,intent);
SecondActivity.this.finish();
}
private void init(){
btn_back=findViewById(R.id.btn_back);
tv_bmi=findViewById(R.id.textView);
Intent intent=getIntent();
height=Double.parseDouble(intent.getStringExtra("height"));
weight=Double.parseDouble(intent.getStringExtra("weight"));
bmi=weight/(height*height);
tv_bmi.setText("您的BMI值为:"+bmi);
btn_back.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
returnData();
}
});
}
}
layout1.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@+id/et_weight"
android:layout_centerHorizontal="true"
android:inputType="text"
android:hint="身高(m)"
android:ems="10"
android:id="@+id/et_height"/>
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:inputType="text"
android:hint="体重(kg)"
android:ems="10"
android:id="@+id/et_weight"/>
<Button
android:text="计算BMI"
android:layout_centerHorizontal="true"
android:layout_below="@id/et_weight"
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:id="@+id/btn_BMI"/>
<TextView
android:text=" "
android:layout_centerHorizontal="true"
android:layout_above="@id/et_height"
android:textSize="30dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:id="@+id/tv_bmiVlues"/>
</RelativeLayout>
layout2.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:text="返回"
android:layout_centerInParent="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:id="@+id/btn_back" android:layout_weight="1"/>
<TextView
android:text=" "
android:textSize="30dp"
android:layout_centerHorizontal="true"
android:layout_above="@id/btn_back"
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:id="@+id/textView"/>
</RelativeLayout>
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" >
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.Homework2"
tools:targetApi="31" >
<activity
android:name=".MainActivity2"
android:exported="false"
android:label="@string/title_activity_main2"
android:theme="@style/Theme.Homework2" />
<activity
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>
<activity
android:name=".SecondActivity"
android:exported="true" >
<intent-filter>
<action android:name="com.example.activity.second" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>