安卓学习笔记三--------四大组件之Activity

目录

一、什么是activity

二、activity生命周期

onCreate

onStart

onResume

onPause

onStop 

onDestroy

onRestart

三、不同生命周期方法的对比

1. onCreate()和onStart()的区别

2. onStart()和onResume()的区别

3. onPause()和onStop()的区别

4. onStop()和onDestroy()

四、任务栈Task(也叫任务)

五、启动方式

1. 标准模式 standard

2. singleTop 栈顶复用模式

3. singleTask 栈内复用模式

4. singleInstance 单例模式

taskaffinity 属性

lauchMode属性

六、activity组件互相调用的demo



一、什么是activity

一个应用程序当中通常都会包含很多个Activity,每个Activity都是一个具有特定的功能,并且可以让用户进行操作的组件。另外,Activity之间可以相互启动,当前应用的Activity甚至可以去启动其他应用的Activity。可以通俗地认为一个activity代表的是一个窗口界面,应用程序的每一个界面都是一个Activity,所以也有人称其为视图界面。大多数APP包含多个界面,那么也意味着它包含了多个activity。而不管一个APP由多少个activity组成,它都只有一个MainActivity(主activity),也就是用户启动APP后看到的第一个界面,在程序工程中,MainActivate也是作为启动APP程序的入口。如下图:

 

二、activity生命周期

onCreate

这是Activity生命周期的第一个方法,也是安卓开发中接触最多的生命周期方法,它的作用主要是做一些初始化工作,比如使用setContentView加载布局和对一些变量和控件初始化等等。若把与初始化不想关的代码放在这里,是不规范的。此时的Activity还在后台,是看不到的。由于不可见,所以动画的初始化一般不放在这。

onStart

表示启动。这是Activity生命周期的第二个方法,此时的Acitvity已经可见了,但是由于还没有出现在前台中,无法进行交互。个时候可以理解为Activity已经显示出来,但是我们还看不到。其实将Activity的初始化工作放在这也没有什么问题,放在onCreate中是由于官方推荐的以及我们开发的习惯。

onResume

这是Activity生命周期的第三个方法,此时的Activity已经可以与用户交互了。

onPause

表示暂停,当Activity要跳到另一个Activity或当应用正常退出时,都会执行此方法。在一个Activity进行跳转时,只有当当前Activity执行完onPause方法后另一个Activity才会启动。

onStop 

表示停止,此时Activity为不可见状态,但是Activity还在内存中,没有被销毁。

onDestroy

表示毁灭,这个阶段的Activity要被销毁掉,这个时候Activity不可见。然后会做一些资源的回收和释放工作。

onRestart

表示重新开始,此时的Activity可见,当用户按Home键从当前Activity切到桌面又切回来或者切到另一个Activity后又切回来时,就会调用这方法。这个方法 一般不做什么操作。

 

整体流程如下图:

当Activity启动时,依次执行onCreate()、onStart()、onResume()方法,此时,Activity界面就可以与用户交互了。

当用户切换到另一个Activity时,原来的Activity就会执行onPause()方法,若原来的Activity还没执行onStop()便又切回来了,那么就会调用onResume()。否则若原来的Activity已经执行了onStop(),那么想切回来,就会执行onRestart()方法。

 

三、不同生命周期方法的对比

1. onCreate()和onStart()的区别

两者的执行次数不同,onCreate只会在创建Activity时执行一次,而onStart在Activity切换的时候以及按Home键再切换回应用的时候都会被调用。

onCreate能做的事onStart其实都能做,但是onstart能做的事onCreate却未必适合做。如前文所说的,setContentView和资源初始化在两者都能做,然而像动画的初始化在onStart中做比较好。

2. onStart()和onResume()的区别

onStart过程中,Activity可见,但不在前台,用户没法交互。但onResume过程中,Activity则在前台,是可以与用户交互的,

3. onPause()和onStop()的区别

onPause可见。onStop时不可见,但是Activity依然是存在于内存中。

4. onStop()和onDestroy()

onStop时Activity还没被销毁,仍然存在于内存当中,可以通过切换再次回到该Activity当中。

而onDestroy则是把Activity销毁了。

 

四、任务栈Task(也叫任务)

什么是任务栈

任务可以看作是Activity,这些Activity按照打开顺序存放在栈中,即后进先出的顺序。这就是任务栈。与用户交互的Activity 存放在栈顶。启动一个Application的时候,系统会为它默认创建一个对应的Task,用来放置根Activity。默认启动Activity会放在同一个Task中,新启动的Activity会被压入启动它的那个Activity的栈中,并且显示它。当用户按下回退键时,这个Activity就会被弹出栈,按下Home键回到桌面,再启动另一个应用,这时候之前那个Task就被移到后台,成为后台任务栈,而刚启动的那个Task就被调到前台,成为前台任务栈,Android系统显示的就是前台任务栈中的Top实例Activity。

例:当我们在社交软件设置用户头像时一般会有拍照和相册两个选项,选择拍照会跳转到摄像机软件,选择相册会跳到系统相册软件。通过这几个软件之间的共同合作完成了一次任务。

任务栈有什么用

以往基于应用(application)的程序开发中,程序具有明确的边界,一个程序就是一个应用,一个应用为了实现功能可以采用开辟新线程甚至新进程来辅助,但是应用与应用之间不能复用资源和功能。

而Android引入了基于组件开发的软件架构,虽然我们开发android程序,仍然使用一个apk工程一个Application的开发形式,但是对于Aplication的开发就用到了Activity、service等四大组件,其中的每一个组件,都是可以被跨应用复用的,这就是android的神奇之处。

 

五、启动方式

1. 标准模式 standard

默认启动模式,启动activity时直接创建新的实例并压入启动它的任务栈顶。

2. singleTop 栈顶复用模式

该模式唯一与standard不同的就是,如果启动singleTop模式的activity时发现当前任务的栈顶已经存在着这个activity的实例,那么就不会创建新的实例,而是调用该实例的onNewIntent()方法。其他的跟标准模式一样。

3. singleTask 栈内复用模式

说的singleTask模式,就不得不介绍一下taskAffinity属性,这个属性是对Activity对应的task栈命名的,默认情况下,所有Activity所需要的任务栈的名字是应用的包名,换句话说就是所有的Activity都用的同一个任务栈。
在singleTask模式下,启动Activity A,会先检测A对应的任务栈存不存在,不存在的话,就创建所需的任务栈,并完成初始化A,入栈行为。如果A对应的栈存在的话,要检测该栈中是否已有A的实例(A之前是否已经入栈过),如果没有,那就初始化实例,入栈;如果有的话,那就把该元素移至栈顶,该元素之前的元素全都移除出栈。

如:

4. singleInstance 单例模式

singleInstance模式和singleTask模式有点像,他们都是单实例模式的,即只有一个实例。但是singleInstance比严格点。当启动一个launch mode为singleInstance模式的Activity的时候,系统会为该Activity单独创建一个专属的任务栈,为其所用。当重复启动该Activity的时候,由于栈中已有该实例,就直接复用就好。

 

taskaffinity 属性

返回栈这个概念对应的就是 taskAffinity,是 Activity 在 AndroidManifest 文件中声明的一个属性值。taskAffinity 翻译为“亲和性”,用于表示特定 Activity 倾向于将自身存放在哪个任务栈中

在默认情况下,同一应用中的所有 Activity 会具有相同的亲和性,所有 Activity 默认会以当前应用的 applicationId 作为自己的 taskAffinity 属性值。我们可以手动为应用内的部分 Activity 指定特定的 taskAffinity,从而将这部分 Activity 进行分组

lauchMode属性

launchMode 一共包含四种属性值,分别对应4种启动模式。 在AndroidManifest 文件中为 Activity 定义 launchMode 属性值

 

六、activity组件互相调用的demo

在Android的程序设计中,可在主程序里使用startActivity() 这个方法来调用另一个Activity(主程序本身即是一个Activity),但当中的关键并不在startActivity这个方法,而是Intent这个特有的对象,Intent就如同其英文字义,是"想要"或"意图"之意,在主Activity当中,告诉程序自己是什么,并想要前往哪里,这就是Intent对象所处理的事了。

首先,需要自定义一个Activity:

Activity1.java

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

import androidx.annotation.Nullable;

public class Activity1 extends Activity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.mylayout);

        Button b2 = (Button)findViewById(R.id.button2);
        b2.setOnClickListener(new Button.OnClickListener(){
            @Override
            public void onClick(View v) {
                Intent intent = new Intent();
                intent.setClass(Activity1.this,MainActivity.class);

                startActivity(intent);
                Activity1.this.finish();
            }
        });
    }
}

然后绘制Activity1的布局文件--- mylayout.xml

在res目录下,新建一个文件: mylayout.xml

<?xml version="1.0" encoding="utf-8"?>
<AbsoluteLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent" android:layout_height="match_parent">

    <TextView
        android:id="@+id/textView2"
        android:layout_width="164dp"
        android:layout_height="36dp"
        android:layout_x="133dp"
        android:layout_y="218dp"
        android:text="this is other Activity" />

    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_x="131dp"
        android:layout_y="331dp"
        android:text="Go to mainActivity" />
</AbsoluteLayout>

再给主Activity界面加入一个按钮,该按钮可以通过点击来转换到另一个Activity(即Activity)。

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity {

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

        Button b1 = (Button)findViewById(R.id.button1);
        b1.setOnClickListener(new Button.OnClickListener(){
            @Override
            public void onClick(View v) {
                /* new一个Intent对象,并指定要启动的class */
                Intent intent = new Intent();
                intent.setClass(MainActivity.this,Activity1.class);
                /*开启一个新的Activity*/
                startActivity(intent);
                MainActivity.this.finish();
            }
        });
    }
}

主Activity的布局文件 activity_main.xml如下:(同样是位于res目录下)

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Go to another Activity"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="mainActivity"
        app:layout_constraintBottom_toTopOf="@+id/button1"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.795" />
</androidx.constraintlayout.widget.ConstraintLayout>

最后由于我们新加入了一个Activity,因此需要在Androidmanifest.xml 配置文件中声明一下 Activity1:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.callantheractivity">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

</manifest>

此外,在两支Java程序中的最后一行都调用了finish() 这个方法,它代表这个Activity已运作完毕,当系统接收到这个命令时,即会关闭此Activity,所以此时点击模拟器的返回(Back)键,并不会回到上一个Activity的画面,如果要让模拟器的返回键有回上一页的效果,可以将此行程序注释掉。同理,当两个Activity在切换时,并非真的只有两个Activity在切换,而是在点击按钮时,再重新调用起一个新的Activity。

运行结果:

Reference:

https://www.jianshu.com/p/fb44584daee3

https://zhuanlan.zhihu.com/p/276424273

https://zhuanlan.zhihu.com/p/366027317

https://www.cnblogs.com/McCa/p/4497928.html

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值