文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Android从入门到放弃—— 一、Activity详解1

2022-06-06 14:21

关注

门——Activity(一) Activity是什么:

Activity作为Andorid的四大组件之一,为用户提供了一个界面,即我们能看到的界面。相当于一张画画用的纸,我们可以在上面画任何我们想要的内容。

Activity的创建:

就像我们画画需要拿一张画纸铺在画板上一样,想要看到界面我们也需要创建一个Activity。创建的方法很简单,分为2步:

继承Activity类

在AndroidManifest.xml文件中配置

这里是使用Android Studio创建项目默认创建的MainActivity代码


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

AndroidManifest.xml



代码分析:

我们上面说第一步是要新建一个类继承自Activity,但是我们的MainActivity是继承的AppCompatActivity类。大家看名字就能知道这个是Activity的子类。当然你也可以手动修改为Activity类。之后的setContentView(R.layout.activity_main)是为当前界面设置一个布局文件,布局文件中就可以放下我们需要的各种控件,这里activity_main布局文件中有一个TextView,显示的文本内容是Hello Word。

我们再看AndroidManifest的内容:

在AndroidManifest中我们只需要关注activity标签中的内容。android:name属性指定当前配置的activity名称,这里配置的是” .MainActivity”,注意,前面有一个点,是相对路径,即当java代码包的根路径下的MainActivity文件。里面的intent-filter内容:表示启动当前app的默认界面。 表示当前的activity会在桌面(launcher)显示一个图标。

运行程序可以在手机或者模拟器看到当前界面显示hello word字样。

启动Activity:

首先我们需要自己创建一个Activity,操作如下图:

点击Finish完成即可,这样就创建好了一个Activity,同时AS也帮我们创建好了一个布局文件activity_second。

进入布局文件,我们同样的添加一个TextView:


这里完成了第二个Activity的创建。回到activity_main.xml布局中,给TextView添加一个Id,同时改变显示的文字。

记住必须要在Manifest文件中配置:


    

这里添加了一个activity标签,android:name属性值为".SecondActivity",同样的前面有一个点,因为我们的SecondActivity也是在当前项目的根目录,所以这里的路径就直接写。如果还有子包,则这里的路径需要加上。

在MainActivity的代码中添加如下代码:


override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        acMainTvJump.setOnClickListener {
            val intent = Intent(this, SecondActivity::class.java)
            startActivity(intent)
        }
    }

运行程序,然后点击MainActivity文本,界面就会跳转到我们刚刚建立的SecondActivity中。

代码分析:

创建SecondActivity的代码比较简单就不做介绍了,主要的代码就在MainActivity中添加的4行代码。

acMainTvJump为textView的ID,这里使用了kotlin语言,kotlin相关的内容这里就不做介绍了。通过设置textview的点击事件,我们在点击时进行activity的跳转。其中关键的一个类:Intent。Intent可以理解为我们想要完成某一件事情的意图,这里我们的意图是跳转到SecondActivity,其构造方法接受2个参数(Intent的构造方法有很多):

可以看到这里第一个参数为packageContext,这里可以直接传入this。第二参数为class,即我们需要跳转的activity。

Activity的生死历程:

要了解Activity的生命周期,这里就不得不祭出官方的祖传图了:

Activity 类提供六个核心回调:onCreate()、onStart()、onResume()、onPause()、onStop() 和 onDestroy()

onCreate:这个方法是我们必须要重写的,activity刚刚创建的是系统会调用这个方法,我们通过setContentView来为Activity设置布局,可以是布局ID,也可以是直接用代码写的一个View。这个时候Activity还是不可见的。

onStart:这个时候Activity已经可见了,相当于我们的界面经过onCreate已经准备好了。但是Activity并不是一直处于这个状态,系统调用完这个方法后会进入下一阶段。

onResume:这个状态Google定义为“已恢复”状态,这个时候Activity进入前台,将长期处于当前状态,并且能和用户进行交互。

onPause:当发生中断事件时,Activity 进入已暂停状态,系统调用 onPause() 回调。这里的中端事件有点模糊,待会我们可以用代码来模拟。如果 Activity 从onPause状态返回“已恢复”状态,系统将再次调用 onResume() 方法。此方法表示 Activity 不再位于前台(尽管如果用户处于多窗口模式,Activity 仍然可见)

onStop:这个时候Activity已经不可见,比如我们新启动了一个Activity覆盖了当前的Activity。

onDestroy:调用此方法时Activity被销毁。如用户按下返回键、代码中调用finish。

通过图片我们看到还有一个方法:onRestart,这个回调发生在重新进入Activity的时候。下面我们通过代码来实际看看各个回调的调用顺序。

在MainActivity和SecondActivity中都重写这几个回调方法并且打印log


class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        Log.d("MainActivity", "ZLog onCreate :")
        setContentView(R.layout.activity_main)
        acMainTvJump.setOnClickListener {
            val intent = Intent(this, SecondActivity::class.java)
            startActivity(intent)
        }
    }
    override fun onStart() {
        super.onStart()
        Log.d("MainActivity", "ZLog onStart :")
    }
    override fun onResume() {
        super.onResume()
        Log.d("MainActivity", "ZLog onResume :")
    }
    override fun onRestart() {
        super.onRestart()
        Log.d("MainActivity", "ZLog onRestart :")
    }
    override fun onPause() {
        super.onPause()
        Log.d("MainActivity", "ZLog onPause :")
    }
    override fun onStop() {
        super.onStop()
        Log.d("MainActivity", "ZLog onStop :")
    }
    override fun onDestroy() {
        super.onDestroy()
        Log.d("MainActivity", "ZLog onDestroy :")
    }
}

SecondActivity类似,就不贴代码了。同样我们运行程序查看log

看到如图的log,我们启动MainActivity后对应的3个回调被调用,最后停留在onResume这里。这个时候我们点击文本跳转到SecondActivity

我们看到首先被调用的是MainActivity的onPause,为什么?因为这个时候系统是先将当前的Activity设置为暂停状态,放到后台,而后开始准备要显示在前台的SecondActivity,于是SecondActivity开始创建和显示到前台。这个时候MainActivity完全不可见,设置为stop状态。

这个时候我们再点击返回按钮

点击返回按钮发生的事件流程:SecondActivity首先退出前台进入后台(调用onPause),MainActivity准备再次显示进入前台,所以调用了onRestart-onstart-onResume进入前台可见。这个时候SecondActivity不可见(onStop),并且进行销毁(onDestroy)。

Activity启动模式

之前说Activity就像画画的画布,这里的画布我们理解为透明的,我们是可以一层一层的叠加的,类似Photoshop的图层。这个时候添加就有讲究了。Android提供了4种模式:standard、singleTop、singleTask、singleInstance。4种模式的设置同样在Manifest种activity标签配置,android:launchMode="standard"。

standard:这个是默认的模式,也是最简单的模式。即每次启动任何activity都直接在之前的activity上添加。

我们正常启动A,在A种启动B,再在B中启动A。按照图中所示,这个时候栈中应该有3个Activity,我们需要按下3次返回键才能推出APP。上代码看看:

我们在SecondActivity中添加了点击事件,启动MainActivity。注意,2个Activity的onCreate方法中打印了当前的对象的地址

通过打印信息我们可以发现MainActivity出现2次,并且不是同一个实例。我们按下返回键查看,需要按下3次才能退出:

singleTop:这种模式主要是为了应对另一种情况,如果刚刚在SecondActivity中再次启动SecondActivity会怎么样?如果是standard则直接新加一个。但如果我们把SecondActivity的模式设置为singleTop呢?

再来查看log信息

可以看到我们点击事件触发后并没有新的SecondActivity被创建。

当我们设置Activity为singleTop时,会启动一个栈顶复用机制。即如果Activity栈顶的Activity跟我们要启动的Activity是同一个,系统并不会重新创建新的,而是直接使用当前的Activity。可以理解为不做任何操作。

singleTask:有没有感觉singleTop模式并不是那么的完美?只能实现栈顶的复用,那要是返回栈中有,但是不是在栈顶的想要复用呢?对,那就设置singleTask模式吧。为什么验证,我们代码需要再改改。

首先我们把MainActivity设置为singleTask,目的就是重复的启动MainActivity。

在SecondActivity中的点击事件我们就启动MainActivity。即 A——B——A这样的顺序,下面我们看log

可以看到SecondActivity中点击事件触发之后MainActivity并没有重新初始化。那是怎么复用的呢?

我们按下返回键看看

what? 为什么只按了一下返回就退出了?因为它很聪明,直接把MainActivity之上的所有Activity都移除了,直接让自己处于栈顶。

来看一下完整的log

重点是在SecondActivity中点击之后,SecondActivity被销毁了。

singleInstance:这个模式是最复杂的一种。之前的3种模式我们所说的返回栈都是同一个返回栈,而这个会启用新的返回栈。

这里我们先把文件改一下

BActivity设置为singleInstance,A、C为默认,按照A——B——C的顺序启动。

我们在onCreate中打印当前taskId

通过log我们可以看到BActivity的taskId跟其他2个不同,说明B是处在一个新的返回栈中。我们在B中启动了C,可能有的朋友会想,C应该跟B在同一个栈中才对。事实是C还是和A在同一个栈中。这里要特别注意,因为singleInstance是独占栈的模式,这个栈里面只能有B。

这个时候我们再来按下返回键看看

我们看到在C界面按下返回,显示的MainActivity(A),刚刚我们说了 C和A是在一个返回栈,所以C返回之后A就显示出来了,A再返回,当前返回栈就全部退出了,这个时候才会再显示B所在的返回栈,因为B里面只有它一个,所以显示了B,再返回所有的就都返回了,退出APP。

好了,先暂时写到这里,后续还将继续介绍Activity相关的其他内容。

欢迎大家指出错误的地方,我们共同学习。

野狼孤 原创文章 5获赞 0访问量 1694 关注 私信 展开阅读全文
作者:野狼孤


阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-移动开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯