引言
讲述安卓中Activity的作用,安卓的一个Activity相当于一个页面,一个Activity由一个xml
文件与java/kt
文件组成。
XML
- XML用于编写布局与样式(相当于HTML+CSS)
- XML通常位于
res/layout/**.xml
Java/Kt
- Java/Kt用于编写逻辑(相当于JS)
- Java/kt通常位于
包名/**.java
或包名/**.kt
Activity 创建
1:创建 Java/Kotlin 类并继承 AppCompatActivity
scala
package com.example.myapplication;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 设置当前 Activity 所使用的布局文件
setContentView(R.layout.activity_main);
}
}
- 创建对应的 XML 布局文件
res/layout/activity_main.xml
xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="这是主页" />
<Button
android:id="@+id/btnNext"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="跳转到下一页" />
</LinearLayout>
3:在 AndroidManifest.xml 中注册 Activity
xml
<application
android:allowBackup="true"
android:label="My Applicaiton">
<!-- 主 Activity -->
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" /> <!--标记为主界面-->
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
Activity 跳转
Activity 之间可以通过 Intent
实现跳转和通信。分为 显式 Intent 跳转 和 隐式 Intent 跳转。
显式跳转
主要用于本应用内的跳转。显式跳转需要手动指定调转到那个 Activity
- 当前上下文(Context),表示从哪个页面跳转出去
- 目标页面的类对象,告诉系统要跳转到哪个 Activity
java
// 在 MainActivity.java 中
Button btnNext = findViewById(R.id.btnNext);
btnNext.setOnClickListener(v -> {
Intent intent = new Intent(MainActivity.this, SecondActivity.class);
startActivity(intent);
});
隐式跳转
适用于调用系统应用或其他应用提供的功能,例如打开浏览器、拨打电话等。不直接指定目标组件,而是通过动作(Action)和数据(Data)让系统匹配合适的组件。依赖 <intent-filter>
来决定哪个应用或组件响应这个 Intent。需要同时匹配对应的 action
与 category
可能会弹出"选择器"让用户选择处理的应用。
比如
xml
<activity android:name=".SecondActivity>
<intent-filter>
<action android:name="com.example.myapplication.ACTION"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
其中action与category中的内容,就是在Intent
中需要填入的内容
java
Intent intent = new Intent("com.example.myapplication.ACTION");
// 安卓可自动填入android.intent.category.DEFAULT
// intent.addCategory("android.intent.category.DEFAULT")
必须有可跳转的1到多个Activity
action与categoty内的内容可自定义
这个方式主要用于跳转系统应用,比如启动浏览器
java
Intent intent = new Intent(Intent.ACTION_VIEW); intent.setData(Uri.parse("https://www.example.com"));
startActivity(intent);
启动电话
java
Intent intent = new Intent(Intent.ACTION_DIAL);
intent.setData(Uri.parse("tel:10086")); startActivity(intent);
对比项 | 显式跳转 | 隐式跳转 |
---|---|---|
是否指定目标组件 | 是(必须) | 否(通过 Action/Data 匹配) |
是否需要注册 intent-filter | 否 | 是(目标组件需声明) |
是否可能弹出选择器 | 否 | 是 |
应用场景 | 本应用内跳转 | 系统功能调用或跨应用通信 |
安全性 | 更安全 | 有一定风险(可能启动未知组件) |
Activity相互传递数据
Activity 生命周期

- onCreate()。在每个Activity中都重写了这个方 法,它会在Activity第一次被创建的时候调用。在这个方法中完成Activity的初始化操作,比如加载布局、绑定事件等。
- onStart()。这个方法在Activity由不可见变为可见的时候调用。
- onResume()。这个方法在Activity准备好和用户进行交互的时候调用。此时的Activity一 定位于返回栈的栈顶,并且处于运行状态。
- onPause()。这个方法在系统准备去启动或者恢复另一个Activity的时候调用 。通常会在这个方法中将一些消耗CPU的资源释放掉,以及保存一些关键数据,但这个方法的执行速度一定要快,不然会影响到新的栈顶Activity的使用。
- onStop()。这个方法在Activity完全不可见的时候调用。它和onPause()方法的主要区别在于,如果启动的新Activity是一个对话框式的Activity,那么onPause()方法会得到执行,而onStop()方法并不会执行。
- onDestroy()。这个方法在Activity被销毁之前调用,之后Activity的状态将变为销毁状态。
- onRestart()。这个方法在Activity由停止状态变为运行状态之前调用,也就是Activity 被重新启动了。
TIP: onPause与onStop的相同点为,此时都启动了新的Activity。但区别是是否新的Activity是全屏的。
这些生命周期基本是两两相对的,比如 onCreate <--> onDestory
, onStart <--> onStop
, onResume <--> onStop
以及onStart
savedInstanceState 与 onSaveInstanceState()
你是否疑惑,为什么onCreate带有参数savedInstanceState
,这有什么用?
先关注下生命周期,从生命周期上来看我们发现了App process killed
。对的,处于暂停状态的Activity有可能会被系统回收,再次进入就需要重新onCreate
,如果我们的Activity是无状态的倒还好,但是如果其中存储了以下数据,此时就会导致数据丢失。所以安卓就提供了savedInstanceState
,来让我们在Activity被回收前保存数据
java
// Acitivty被回收前调用
@Override
protected void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
}
- savedInstanceState 仅适用于临时性的 UI 状态数据,不适用于持久化存储
- savedInstanceState 不适合存储复杂的大对象
Activity 启动模式
安卓系统使用栈 的结构来管理Activity,设备页面上的Acitivity位于栈顶。运行中Activity(实例)也被称为一个Task。
standard
standard是Activity默认的启动模式,在不进行显式指定的情况下,所有Activity都会自动使用这种启动模式。
在standard模式下,
- 每当启动一个新的Activity,它就会在返回栈中入栈,并处于栈顶的位置。
- 系统不会在乎这个Activity是否已经在返回栈中存在,每次启动都会创建一个该 Activity的新实例。
singleTop
相对于standard重复创建新的实例,singleTop在启动Activity时
- 如果发现返回栈的栈顶已经是该Activity ,则认为可以直接使用它,不会再创建新的Activity实例
- 但当启动的Activity不在栈顶 ,则依然会创建新实例。
singleTask
singleTop仅仅保证栈顶不重复,如果该Activity并没有处于栈顶的位置,还是可能会创建多个Activity实例。而当Activity的启动模式指定为singleTask时
- 每次启动该Activity时,系统首先会在返回栈中检查是否存在该Activity的实例,如果发现已经存在则直接使用该实例, 并把在这个Activity之上的所有其他Activity统统出栈
- 如果没有发现就会创建一个新的 Activity实例。
singleInstance
单例模式,指定为singleInstance模式的Activity会启用一个新的返回栈来管理这个Activity 。主要是为了解决各应用共享Activity 的问题。其他应用与本应用访问该Activity实例时,都会利用该新返回栈。
xml
<activity android:name=".SecondActivity"
android:launchMode="singleInstance"> <!--!!!-->
<intent-filter>
<action android:name="com.example.activitytest.ACTION_START" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="com.example.activitytest.MY_CATEGORY" />
</intent-filter>
</activity>
TIP:还需深度了解
Activity的UI:RecyclerView
在 Android 开发中,RecyclerView 是构建复杂、动态列表界面的核心组件之一 。它替代了早期的 ListView 和 GridView,提供了更高的灵活性和性能优化机制。RecyclerView 通常作为 Activity 中的一个重要 UI 组件来展示大量可滚动的数据集合。
RecyclerView 的核心机制依赖于两个关键类:RecyclerView.Adapter
和 RecyclerView.ViewHolder
。
RecyclerView.Adapter
主要作用是将数据绑定到 UI 上,负责创建ViewHolder,并填充ViewHolder中的数据,可以说Adapter是数据与UI的桥梁,主要涉及到3个函数
当 RecyclerView 需要显示一个新的 item 时,如果没有可复用的 viewHolder,Adapter 就会通过 onCreateViewHolder()
方法来创建一个新的 ViewHolder。
ViewHolder 在构造时会加载并持有 item 的布局文件(如 item_layout.xml),从而为后续的数据绑定提供 UI 容器。
java
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_layout, parent, false);
return new MyViewHolder(view);
}
onBindViewHolder() 方法负责将指定位置的数据绑定到对应的 ViewHolder 上,即更新 UI 内容。
java
@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
ItemData item = dataList.get(position);
holder.textView.setText(item.getTitle());
}
getItemCount() 方法告诉 RecyclerView 中有多少数据,从而决定创建多少个ViewHolder。
java
@Override
public int getItemCount() {
return dataList.size();
}
- 当
RecyclerView
需要显示视图的时候,首先找Adapter
,调用它的getItemCount()
函数,询问数组列表中一共有多少个对象需要显示。 - 随后继续调用
onCreateViewHolder()
函数,创建相应的ViewHolder
对象和ViewHolder
需要显示的view
。 - 接着调用
onBindViewHolder()
,得到对应的ViewHolder和位置,将数据绑定到ViewHolder
视图上,也就是去修改具体的控件。
RecyclerView.ViewHolder
负责容纳View视图(具体控件)。也就是RecyclerView中填充的视图是由ViewHolder提供的。在创建ViewHolder时会传入相应的布局,然后通过布局去配置具体的控件。
java
public class MyViewHolder extends RecyclerView.ViewHolder {
public TextView textView;
public ImageView imageView;
public MyViewHolder(View layout) {
super(itemView);
textView = layout.findViewById(R.id.text_view);
imageView = layout.findViewById(R.id.image_view);
}
}
一个 Adapter 持有多个 ViewHolder,每个 ViewHolder 又持有多个控件
组件 | 数量 | 描述 |
---|---|---|
Adapter | 1 个 | 控制整个列表的数据和展示逻辑,协调多个 ViewHolder |
ViewHolder | 多个(根据可见 item 数量动态创建) | 每个 ViewHolder 对应一个 item 布局实例 |
View / 控件 | 每个 ViewHolder 中持有多个 | 如 TextView、ImageView 等 UI 控件 |