【android】Activity的使用

本文详细介绍了Android中的Activity组件,包括使用方法、生命周期管理、启动模式、数据交互方式等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、Activity

Activity 是一种可以包含用户界面的组件,主要用于和用户交互。一个应用程序中可以包含零个或多个活动。

1.1、Activity 的使用

(1)、继承 Activity,实现 Activity 的生命周期方法。

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    @Override
    protected void onStart() {
        super.onStart();
    }

    @Override
    protected void onStop() {
        super.onStop();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
    }

    @Override
    protected void onPause() {
        super.onPause();
    }

    @Override
    protected void onResume() {
        super.onResume();
    }
}

(2)、在 AndroidManifest.xml 文件中注册 Activity。

 <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

1.2、Activity的生命周期

1.2.1、典型情况下的生命周期

这里写图片描述

  • onCreate(): 初始化
  • onRestart(): Activity 重新启动,从不可见重新变为可见状态
  • onStart(): 已经可见,但没有出现在前台,无法与用户交互,看不见
  • onResume(): 可见,并在前台开始活动
  • onPause(): 存储数据,停止动画等。需要不能太耗时
  • onStop(): 做稍微重量级的回收操作,同样不能太耗时
  • onDestroy(): 做一些回收工作和最终的资源释放

PS:onCreate 和 onDestory:是否存在

​ onStart 和 onStop:是否可见

​ onResume 和 onPause:是否位于前台

1.2.2、异常情况下的生命周期

情况一:资源相关的系统配置发生改变导致 Activity 被杀死并重新创建。
这里写图片描述

  • onSaveInstanceState(): 是用来保存当前 Activity 的状态,这个方法调用的时机是在 onStop() 之前,它和 onPause() 没有既定的时序关系,正常情况下不会被调用。

  • onRestoreInstanceState(): 将 Activity 销毁时 onSaveInstanceState() 方法所保存的 Bundle 对象作为参数同时传递给 onRestoreInstanceState() 和 onCreate() 方法。

  • onSaveInstanceState() 和 onRestoreInstanceState() 方法中,系统自动为我们做了一定的恢复工作,默认保存当前Activity的视图结构,包括View的相关状态。

和 Activity 一样,每一个 View 都有 onSaveInstanceState() 和 onRestoreInstanceState() 这两个方法。关于保存和恢复 View 层次结构,系统的工作流程是这样的:首先Activity被意外终止是,Activity 会调用 onSaveInstanceState 去保存数据,然后 Activity 会委托 Window 去保存数据,接着 Window 再委托它上面的顶级容器去保存数据。顶层容器是一个 ViewGroup,一般来说是 DecorView。最后顶层容器再去一一通知它的子元素来保存数据,这样,整个数据保存的动作就完成了。

情况二:资源内存不足导致低优先级的 Activity 被杀死

Activity 按照优先级从高到低,可以分为三种:

  1. 前台 Activity——正在和用户交互的 Activity,优先级最高。
  2. 可见但非前台 Activity——比如 Activity 弹出了一个对话框,导致 Activity 可见但是位于后台无法和用户直接交互。
  3. 后台 Activity——已经被暂停的 Activity,比如执行了 onStop() 方法,优先级最低。

当系统内存不足时,系统就会按照上述优先级去杀死目标 Activity 所在的进程。如果一个进程中没有四大组件再执行,那么这个进程将很快被系统杀死,因此,一些后台工作不适合脱离四大组件而肚子运行在后台,这样进程很容易被杀死。比较好的方法是将后台工作放入 Service 中从而保证进程有一定的优先级,这样就不会轻易地被系统杀死。

如果当某项系统配置发生改变后,我们不想系统重新创建 Activity,可以给 Activity 指定 configChanges 属性。比如不想让 Activity 在屏幕旋转地时候重新创建,就可以给 configChanges 属性添加 orientation 这个值。如果想指定多个值,可以用“|”连接起来。

eg: android:configChanges = "orientation"

1.3、Activity的启动模式

1.3.1、四种启动模式

  • standard 标准模式,默认模式。每次启动 Activity 都会重新创建一个新的实例,不管这个实例是否已经存在。在这个模式下,谁启动了这个Activity,那么这个 Activity 就运行在启动它的那个 Activity 所在的栈中。
  • singleTop 栈顶复用模式。在这种模式下,如果 Activity 已经位于任务栈的栈顶,那么此Activity不会被重新创建,同时它的onNewIntent方法会被毁掉,通过此方法的参数我们可以取出当前的请求的信息。
  • singleTask 栈内复用模式。这是一种单实例模式,在这种模式下,只要 Activity 在一个栈中存在,那么多次启动此 Activity 都不会重新创建实例,和 singleTop 一样,系统也会自动调用其 onNewIntent。同时由于 singleTask 默认具有 clearTop 的效果,会导致栈内所有在被启动的 Activity 上面的 Activity 全部出栈,最终被启动的Activity留在栈顶。
  • singleInstance 单实例模式。这是一种加强的 singleTask 模式,它除了具有 singleTask 模式的所有特性外,还加强了一点,那就是具有此种模式的 Activity 智能单独地位于一个任务栈中。

PS:任务栈:TaskAffinity,可以被翻译成任务相关性。这个参数标识了一个 Activity 所需要地任务栈的名字,默认情况下,所有 Activity 所需的任务栈的名字为应用的包名。我们也可以为每个 Activity 都单独指定 TaskAffinity 属性,这个属性值必须不能和包名相同,否则就相当于没有指定。TaskAffinity 属性主要和 singleTask 启动模式或者 allowTaskReparenting 属性配对使用,在其他情况下没有意义。任务栈分为前台任务栈和后台任务栈,后台任务栈中的 Activity 处于暂停状态,用户可以通过切换将后台任务栈再次调到前台。

1.3.2、指定启动模式

方法一: 通过 AndroidMenifest 为 Activity 指定启动模式。

<activity 
            android:name=".MainActivity"
            android:launchMode="singleTask">

方法二: 通过在Intent中设置标志位来为 Activity指 定启动模式。

Intent intent = new Intent();
intent.setClass(MainActivity.this,SecondActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);

当两种同时存在时,以第二种为准;第一种方式无法直接为 Activity 设定 FLAG_ACTIVITY_CLEAR_TOP 标识,而第二种无法为 Activity 指定 singleInstance 模式。

1.3.3、Activity 的 Flags

标记位含义
FLAG_ACTIVITY_NEW_TASKsingleTask启动模式
FLAG_ACTIVITY_SINGLE_TOPsingleTop启动模式
FLAG_ACTIVITY_CLEAR_TOP具有此标记位的 Activity,当它启动时,在同一个任务栈中所有位于它上面的 Activity 都要出栈
FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS当某些情况下我们不希望用户通过历史列表回到我们的 ACtivity 的时候有用

1.4、Activity 的通讯

在同一个进程中的 Activity 之间的数据交互方式有以下几种:

  1. Intent
  2. 广播

1.4.1、借助 Intent 进行数据交互的几种方式

(1)、传递简单数据

通过 intent 的 putExtra() 和 get***Extra() 方法

MainActivity

Intent intent = new Intent(MainActivity.this,SecondActivity.class);
intent.putExtra("msg1","dagedage");
intent.putExtra("msg2","woshixiaodi");
startActivity(intent);

SecondActivity

Intent intent = getIntent();
textView.setText(intent.getStringExtra("msg2") + "," + intent.getStringExtra("msg2"));

(2)、Bundle传递数据包

MainActivity

 Intent intent = new Intent(MainActivity.this,SecondActivity.class);
 Bundle bundle = new Bundle();
 bundle.putString("msg1","dagedage");
 bundle.putString("msg2","woshixiaodi");
 intent.putExtras(bundle);
 startActivity(intent);

SecondActivity

Intent intent = getIntent();
Bundle b = intent.getExtras();
textView.setText(b.getString("msg1") + "," + b.getString("msg2"));

(3)、传递对象

public class UserMessage implements Serializable{
    private String name;
    private String age;
    public UserMessage(String name, String age) {
        this.name = name;
        this.age = age;
    }
    public void setName(String name) {
        this.name = name;
    }
    public void setAge(String age) {
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public String getAge() {
        return age;
    }
}

实现 Serializable 接口,可以对数据进行序列化。

MainActivity

 Intent intent = new Intent(MainActivity.this,SecondActivity.class);
 intent.putExtra("UserMessage",new UserMessage("Chandelier","20"));
 startActivity(intent);

SecondActivity

UserMessage um = (UserMessage)getIntent().getSerializableExtra("UserMessage");
textView.setText(um.getName() + ","+ um.getAge());

1.4.2、使用广播进行 Activity 之间的通讯

在要发送消息的 Activity 中发送广播,然后再要接收消息的 Activity 中定义广播接收者并注册,接收广播。

1.5、Activity 的启动过程

《Android开发艺术探索》第九章讲到了 Activity 的启动过程,非常复杂,经过一系列的交付委托,最终由 performLaunchActivity 方法最终完成了Activity 对象的创建和启动过程,并且 ActivityThread 通过 handleResumeActivity 方法来调用被启动的 Activity 的 onResume 这一生命周期方法。

handleLaunchActivity 源码:

private void handleLaunchActivity(ActivityClientRecord r,Intent customIntent){
  ...
  if(localLOGV) 
    Slog.v(TAG,"Handling launch of " + r);
  Activity a = performLaunchActivity(r,customIntent);
  if(a != null){
    r.createdConfig = new Configuration(mConfiguration);
    Bundle oldState = r.state;
    handleResumeActivity(r.token, false, r.isForward, !r.activity.mFinished && !r.startNotResumed);
    ...
  }
  ...
}

那么 performLaunchActivity 这个方法做了那些事情呢?

  1. 从 ActivityClientRecord 中获取待启动的 Activity 的组件信息
  2. 通过 Instrumentation 的 newActivity 方法使用类加载器创建 Activity 对象
  3. 通过 LoadedApk 的 makeApplication 方法来尝试创建 Application 对象。Application 创建完毕后,系统会通过 Instrumentation 的 callApplicationOnCreate 来调用 Application 的 onCreate 方法
  4. 创建 contextImpl 对象并通过 Activity 的 attach 方法来完成一些重要数据的初始化
  5. 调用 Activity 的 onCreate 方法
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值