美文网首页
Android笔记——Activity

Android笔记——Activity

作者: 莫忘初心_倒霉熊 | 来源:发表于2022-02-11 10:07 被阅读0次

1.0Activity基本操作

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

1.1创建一个Activity

如下代码创建一个MainActivity的Activity,并使用R.layout.activity_main作为布局文件。

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }
}

1.2销毁一个Activity

如果想销毁一个Activity,可以调用Activity类的finish()方法,可以销毁当前的Activity。

        button1.setOnClickListener{
            finish()
        }

1.3跳转Activity

Intent是Android程序中各组件之间进行交互的一种重要方式,它不仅可以指明当前组件想要执行的动作,还可以在不同组件之间传递数据。Intent一般可用于启动Activity、启动Service以及发送广播等场景。

Intent大致可以分为两种:显式Intent和隐式Intent。

  1. 显式Intent

Activity类中提供了一个startActivity()方法,专门用于启动Activity,它接收一个Intent参数,将构建好的Intent传入startActivity()方法就可以启动目标Activity了。

        button1.setOnClickListener{
            val intent = Intent(this,SecondActivity::class.java)
            startActivity(intent)
        }
  1. 隐式Intent

隐式Intent并不明确指出想要启动哪一个Activity,而是指定了一系列更为抽象的action和category等信息,然后交由系统去分析这个Intent,并帮我们找出合适的Activity去启动。

通过在<activity>标签下配置<intent-filter>的内容,可以指定当前Activity能够响应的action和category。

打开AndroidManifest.xml,添加如下代码:

        <activity android:name=".SecondActivity">
            <intent-filter>
                <action android:name="com.example.myapplication.ACRION_START" />

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

在<action>标签中指明了当前Activity可以响应android.intent.action.ACTION_START这个action,而<category>标签则包含了一些附加信息,更精确地指明了当前Activity能够响应的Intent中还可能带有的category。只有<action>和<category>中的内容同时匹配Intent中指定的action和category时,这个Activity才能响应该Intent。
每个Intent中只能指定一个action,但能指定多个category。

代码如下:

        button1.setOnClickListener{
            val intent = Intent("com.example.myapplication.ACRION_START")
            startActivity(intent)
        }

使用Intent的另一个构造函数,直接将action的字符串传了进去,表明我们想要启动能够响应com.example.myapplication.ACTION_START这个action的Activity。android.intent.category.DEFAULT是一种默认的category,在调用startActivity()方法的时候会自动将这个category添加到Intent中。

1.3.1跳转启动浏览器

使用隐式Intent,不仅可以启动自己程序内的Activity,还可以启动其他程序的Activity。例如,打开浏览器,代码如下:

        button1.setOnClickListener{
            val intent = Intent(Intent.ACTION_VIEW)
            intent.data = Uri.parse("https://www.baidu.com")
            startActivity(intent)
        }

Intent.ACTION_VIEW,是一个Android系统内置的动作。运行程序,即可打开浏览器。

可以在<intent-filter>标签中再配置一个<data>标签,用于更精确地指定当前Activity能够响应的数据。<data>标签中主要可以配置以下内容。
● android:scheme 用于指定数据的协议部分,如上例中的https部分。
● android:host 用于指定数据的主机名部分,如上例中的www.baidu.com部分。
● android:port 用于指定数据的端口部分,一般紧随在主机名之后。
● android:path 用于指定主机名和端口之后的部分,如一段网址中跟在域名之后的内容。
● android:mimeType 用于指定可以处理的数据类型,允许使用通配符的方式进行指定。
只有当<data>标签中指定的内容和Intent中携带的Data完全一致时,当前Activity才能够响应该Intent。

1.4向下一个Activity传递数据

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


发送数据

然后在SecondActivity中将传递的数据取出。


接收数据

1.5返回数据给上一个Activity

返回上一个Activity只需要按一下Back键就可以了,并没有一个用于启动Activity的Intent来传递数据,这时需要用到Activity类中用于启动Activity的startActivityForResult()方法。

切换Activity

startActivityForResult()方法接收两个参数:第一个参数还是Intent;第二个参数是请求码,用于在之后的回调中判断数据的来源。

下一个Activity

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

我们使用startActivityForResult()方法来启动SecondActivity的,在SecondActivity被销毁之后会回调上一个Activity的onActivityResult()方法。


数据回调

onActivityResult()方法带有3个参数:第一个参数requestCode,即我们在启动Activity时传入的请求码;第二个参数resultCode,即我们在返回数据时传入的处理结果;第三个参数data,即携带着返回数据的Intent。

如果用户在SecondActivity中并不是通过点击按钮,而是通过按下Back键回到FirstActivity,这时可以通过在SecondActivity中重写onBackPressed()方法来解决这个问题,代码如下所示:


重写onBackPressed()方法

2.0Activity的生命周期

2.1返回栈

Android是使用任务(task)来管理Activity的,一个任务就是一组存放在栈里的Activity的集合,这个栈也被称作返回栈(back stack)。在默认情况下,每当我们启动了一个新的Activity,它就会在返回栈中入栈,并处于栈顶的位置。而每当我们按下Back键或调用finish()方法去销毁一个Activity时,处于栈顶的Activity就会出栈,前一个入栈的Activity就会重新处于栈顶的位置。系统总是会显示处于栈顶的Activity给用户。


返回栈工作示意图

2.2Activity状态

每个Activity在其生命周期中最多可能会有4种状态。

  1. 运行状态:当一个Activity位于返回栈的栈顶时,Activity就处于运行状态。
    系统最不愿意回收的就是处于运行状态的Activity,因为这会带来非常差的用户体验。
  2. 暂停状态:当一个Activity不再处于栈顶位置,但仍然可见时,Activity就进入了暂停状态。因为并不是每一个Activity都会占满整个屏幕,比如对话框形式的Activity只会占用屏幕中间的部分区域。
    处于暂停状态的Activity仍然是完全存活着的,系统也不愿意回收这种Activity,只有在内存极低的情况下,系统才会去考虑回收这种Activity。
  3. 停止状态当一个Activity不再处于栈顶位置,并且完全不可见的时候,就进入了停止状态。
    系统仍然会为这种Activity保存相应的状态和成员变量,但是这并不是完全可靠的,当其他地方需要内存时,处于停止状态的Activity有可能会被系统回收。
  4. 销毁状态一个Activity从返回栈中移除后就变成了销毁状态。
    系统最倾向于回收处于这种状态的Activity,以保证手机的内存充足。

2.3Activity的生存期

Activity类中定义了7个回调方法,覆盖了Activity生命周期的每一个环节。

● onCreate():这个方法在每个Activity第一次被创建的时候调用。
可以在这个方法中完成Activity的初始化操作,比如加载布局、绑定事件等。
● onStart():这个方法在Activity由不可见变为可见的时候调用。
● onResume():这个方法在Activity准备好和用户进行交互的时候调用。
此时的Activity一定位于返回栈的栈顶,并且处于运行状态。
● onPause()。这个方法在系统准备去启动或者恢复另一个Activity的时候调用。
通常会在这个方法中将一些消耗CPU的资源释放掉,以及保存一些关键数据,但这个方法的执行速度一定要快,不然会影响到新的栈顶Activity的使用。
● onStop()。这个方法在Activity完全不可见的时候调用。它和onPause()方法的主要区别在于,如果启动的新Activity是一个对话框式的Activity,那么onPause()方法会得到执行,而onStop()方法并不会执行。
● onDestroy()。这个方法在Activity被销毁之前调用,之后Activity的状态将变为销毁状态。
● onRestart()。这个方法在Activity由停止状态变为运行状态之前调用,也就是Activity被重新启动了。

除了onRestart()方法,其他都是两两相对的,从而又可以将Activity分为以下3种生存期:
● 完整生存期:Activity在onCreate()方法和onDestroy()方法之间所经历的就是完整生存期。
一般情况下,一个Activity会在onCreate()方法中完成各种初始化操作,而在onDestroy()方法中完成释放内存的操作。
● 可见生存期:Activity在onStart()方法和onStop()方法之间所经历的就是可见生存期。
在可见生存期内,Activity对于用户总是可见的,即便有可能无法和用户进行交互。可以通过这两个方法合理地管理那些对用户可见的资源。比如在onStart()方法中对资源进行加载,而在onStop()方法中对资源进行释放,从而保证处于停止状态的Activity不会占用过多内存。
● 前台生存期。Activity在onResume()方法和onPause()方法之间所经历的就是前台生存期。
在前台生存期内,Activity总是处于运行状态,此时的Activity是可以和用户进行交互的,我们平时看到和接触最多的就是这个状态下的Activity。

2.4Activity生命周期

Android官方提供了一张Activity生命周期的示意图如下:


Activity生命周期

2.4Activity被回收了

当一个Activity进入了停止状态,是有可能被系统回收的,那如何保存临时数据和状态呢?
可以使用Activity中提供了一个onSaveInstanceState()回调方法,这个方法可以保证在Activity被回收之前一定会被调用,

对临时数据进行保存


保存临时数据

对临时数据进行恢复


恢复临时数据

3.0Activity的启动模式

启动模式一共有4种,分别是standard、singleTop、singleTask和singleInstance,可以在AndroidManifest.xml中通过给<activity>标签指定android:launchMode属性来选择启动模式。

3.1standard

standard是Activity默认的启动模式,在不进行显式指定的情况下,所有Activity都会自动使用这种启动模式。在standard模式下,每当启动一个新的Activity,它就会在返回栈中入栈,并处于栈顶的位置。对于使用standard模式的Activity,系统不会在乎这个Activity是否已经在返回栈中存在,每次启动都会创建一个该Activity的新实例。

standard模式原理示意图

3.2singleTop

当Activity的启动模式指定为singleTop,在启动Activity时如果发现返回栈的栈顶已经是该Activity,则认为可以直接使用它,不会再创建新的Activity实例。当该Activity并未处于栈顶位置时,再启动该Activity还是会创建新的实例的。

修改AndroidManifest.xml中FirstActivity的启动模式,如下所示:


启动模式为singleTop singleTop模式原理示意图

3.3singleTask

当Activity的启动模式指定为singleTask,每次启动该Activity时,系统首先会在返回栈中检查是否存在该Activity的实例,如果发现已经存在则直接使用该实例,并把在这个Activity之上的所有其他Activity统统出栈,如果没有发现就会创建一个新的Activity实例。

修改AndroidManifest.xml中FirstActivity的启动模式,如下所示:


启动模式为singleTask singleTask模式原理示意图

3.4singleInstance

指定为singleInstance模式的Activity会启用一个新的返回栈来管理这个Activity(其实如果singleTask模式指定了不同的taskAffinity,也会启动一个新的返回栈)。在这种模式下,会有一个单独的返回栈来管理这个Activity,不管是哪个应用程序来访问这个Activity,都共用同一个返回栈,也就解决了共享Activity实例的问题。
修改AndroidManifest.xml中SecondActivity的启动模式,如下所示:


启动模式为singleInstance singleInstance模式原理示意图

相关文章

网友评论

      本文标题:Android笔记——Activity

      本文链接:https://www.haomeiwen.com/subject/jnonkrtx.html