Android学习之路--四大组件--Activity

本文深入讲解 Android 开发中 Activity 的生命周期,包括启动、暂停、停止等状态的变化,并探讨了屏幕旋转时 Activity 的行为表现。

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

四大组件


一 、Activity

      Android开发中,我们用的东西往往离不开这四个家伙,因为他们在设计之初就是在考虑类似MVC模式开发模式设计的。我们先来学习下最常见的,HelloWorld的出生地就是大名鼎鼎的Activity。我们在这里先介绍些生命周期、屏幕翻转的东西。

      · 生命周期

      Activity,我们在第一眼看到HelloWorld的时候,它其实是做了很多功课的,初始化了一大堆的东西,这些我们现在暂时不用管,以后我们在讲,现在我们管的就是正确的看到HelloWorld就行,但是Activity自身它也有自己的生命周期。按照谷歌官方解释,看下图:

这其实是很全面的了,但我们还是要结合实际,如果您的English是在2级半(拼音)的话,那我们还是在手机上真枪实战一下吧,具体看看它的生命周期是怎么走的。
程序很简单。就是写出各大生命周期,然后打印日志。

public class TestActivity extends Activity{
    private String tag =TestActivity.class.getSimpleName();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.test);
        Log.i(tag,"oncreate");
        TextView tv = (TextView) findViewById(R.id.tv);
        tv.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startActivity(new Intent(TestActivity.this,       TestListActivity.class));
            }
        });
    }

    @Override
    protected void onStart() {
        super.onStart();
        Log.i(tag,"onstart");
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.i(tag,"onresume");
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.i(tag,"onparse");
    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.i(tag,"onstop");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.i(tag,"ondestory");
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        Log.i(tag,"onSaveInstanceState");
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        Log.i(tag,"onRestoreInstanceState");
    }
}

测试case

1.程序启动,就是点击应用图标后,

.599 1811-1811/com.android.app I/TestActivity: oncreate
.603 1811-1811/com.android.app I/TestActivity: onstart
.603 1811-1811/com.android.app I/TestActivity: onresume

2.跳转到其他页面

.920 5589-5589/com.android.app I/TestActivity: onparse
.478 5589-5589/com.android.app I/TestActivity: onSaveInstanceState
.478 5589-5589/com.android.app I/TestActivity: onstop

3.跳转后在回到当前页面

.149 5589-5589/com.android.app I/TestActivity: onstart
.149 5589-5589/com.android.app I/TestActivity: onresume

4.按Home键

.003 5589-5589/com.android.app I/TestActivity: onparse
.005 5589-5589/com.android.app I/TestActivity:onSaveInstanceState
.005 5589-5589/com.android.app I/TestActivity: onstop

5.按Home后在回来

.399 5589-5589/com.android.app I/TestActivity: onstart
.399 5589-5589/com.android.app I/TestActivity: onresume

6.按back键退出程序

.669 31873-31873/com.android.app I/TestActivity: onparse
.136 5589-5589/com.android.app I/TestActivity: onstop
.136 5589-5589/com.android.app I/TestActivity: ondestory

在这里我们有俩个谷歌里没有添加的俩个方法,onSaveInstanceState和onRestoreInstanceState。这俩个方法是在内存不够时,程序被回收时执行onSaveInstanceState,然后在进入程序执行的onRestoreInstanceState的方法。当我们的设备内存不够时,我们可以在这里(Bundle)保存一些重要的信息,然后程序重新进入时,最初的oncreate方法里Bundle里就不为空了,就可以恢复些之前的数据,比如说列表滑到哪了,tab在原来的第几个啦等等。


      · 屏幕翻转
      安卓屏幕翻转就是在打开应用后屏幕在横屏、竖屏之间来回切换,在切换后,Activity的生命周期也是要变换的。
程序还是之前的程序,我们直接转换屏幕即可。

测试模拟器API:23,设备6.0。
测试case1:manifest中啥也不设置。

1.竖屏切横屏

.111 1742-1742/com.android.app I/TestActivity: onparse
.112 1742-1742/com.android.app I/TestActivity:onSaveInstanceState
.112 1742-1742/com.android.app I/TestActivity: onstop
.112 1742-1742/com.android.app I/TestActivity: ondestory

.124 1742-1742/com.android.app I/TestActivity: oncreate
.124 1742-1742/com.android.app I/TestActivity: onstart
.124 1742-1742/com.android.app I/TestActivity: onRestoreInstanceState
.125 1742-1742/com.android.app I/TestActivity: onresume

我们看到,当竖屏切横屏时,之前创建的Activity进行了销毁,但是在销毁之前,进行了数据的保存。在重新创建了一个新的Activity,但是新创建的Activity后,Bundle中是含有之前的保存数据的,而且也是调用了onRestoreInstanceState方法,我们可以在新开启的Activity中进行数据的同步,比如歌曲听到哪了,视频看到哪个进度了等等。

2.横屏切竖屏

.634 1742-1742/com.android.app I/TestActivity: onparse
.634 1742-1742/com.android.app I/TestActivity: onSaveInstanceState
.634 1742-1742/com.android.app I/TestActivity: onstop
.634 1742-1742/com.android.app I/TestActivity: ondestory
.658 1742-1742/com.android.app I/TestActivity: oncreate
.659 1742-1742/com.android.app I/TestActivity: onstart
.659 1742-1742/com.android.app I/TestActivity: onRestoreInstanceState
.659 1742-1742/com.android.app I/TestActivity: onresume

我们看到在安卓6.0上面生命周期也是执行一次销毁,一次创建,而在安卓2.3设备中,其生命周期会走俩次创建。

测试case 2 :manifest中增加configuration

<activity android:name=".TestActivity" android:configChanges="orientation">
 ···
</activity>

在进行以上的流程切换,发现其生命流程是一样的。都是创建一次。

测试case 3 :manifest中在增加一些参数

<activity android:name=".TestActivity" android:configChanges="orientation||keyboardHidden|screenSize">
 ···
</activity

这时,我们在TestActivity中增加一个方法:

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    Log.i(tag,"onConfigurationChanged");
    if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
       Log.i(tag,"landscape");
    } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
       Log.i(tag,"portarit");
   }
}

我们进行竖屏切横屏是,只会走:

.400 23390-23390/com.android.app I/TestActivity: onConfigurationChanged
.400 23390-23390/com.android.app I/TestActivity: landscape

这俩个方法,Activity都没有创建。都是用的同一个,只不过就调用了onConfigChange这个方法.

横屏切竖屏:

.323 23390-23390/com.android.app I/TestActivity: onConfigurationChanged
.323 23390-23390/com.android.app I/TestActivity: portarit

注意:

  • Activity中的组件都是在UI线程中进行管理的,我们要修改这些组件的某些值也只能在UI线程中进行修改,否则会报如下错误:
    android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

至此,Activity的一些知识我们学完了。代码最好都自己敲一遍,看十遍不如自己敲一行,这样便于我们更好的理解与记忆。大家如果有什么问题,欢迎交流,码字辛苦,尊重原创!谢谢各位。

实验四 Android基本组件交互实验 【实验目的】 本实验是Android基本组件实验,主要针对Activity、Service和Receiver实现和使用方 法。通过实验使学生掌握Activity的跳转、Service的启动停止以及Receiver的接受等。 【实验要求】 使得学生熟悉Activity、Service和BroadCast基本使用; 使得学生掌握短信接收实现和使用; 使得学生掌握界面跳转基本原理和使用方法; 使得学生掌握服务和广播的基本机制。 【实验原理】 1. Activity跳转 startActivity——跳转到目标页面,参数为Intent; startActivityForResult ——跳转到下一个Activity,而当这个Activity被关闭以后,自动跳转前一个Activity ,并调用onActivityResult( )方法,参数为Intent和requestcode 2. Intent Android基本的设计理念是鼓励减少组件间的耦合,因此Android提供了Intent (意图) ,Intent提供了一种通用的消息系统,将要执行的动作的抽象的描述,一般来说是作为 参数来使用,由Intent来协助完成Android各个组件之间的通讯 。 Intent属性: Action ,对执行动作的描述,在Intent类中定义了一些字符串常量作为标准动作; data ,是对执行动作所要操作的数据的描述,Android中采用URI来表示数据; 例:VIEW_ACTION content://contacts/1表示显示标识符为"1 的联系人的详细信息。 catagory 类别,是被执行动作的附加信息; extra 附加信息,除了data之外,还可以通过extra附加信息,extra属性使用Bundle类 型进行数据传递; component 组件,显式指定Intent的目标组件的名称; type 数据类型,显式指定Intent的数据类型; 3. Service组件 Service一般由一个Activity或其他Context对象来启动,当启动Service之后,该Se rvice将会在后台运行,及时启动这个Service的Activity或其他组件的生命周期已经结 束,Service仍然会继续运行,直到自己的生命周期结束为止。每个Service都应该在nd roidManifest.xml中进行声明。Service的启动方式有两种,对应的生命周期也各不相同 。 通过startService方法启动。当系统调用startService方法,如果该Service还未启 动,则依法调用其onCreate方法和onStart方法来启动。当其他Context对象调用stopSe rvice方法、Service调用自身的stopSelf或stopService方法时才会停止Service的执行 。 通过bindService方法启动。当系统调用bindService方法时,如果该Service未启动 ,则会调用onCreate方法完成初始化工作,然后会将该Service和Context对象(如Activ ity)进行绑定,当被绑定的Context对象被销毁时,与之绑在一起的Service也会停止运 行。 4. Broadcast Receiver组件 Broadcast Receiver同Service一样,并不提供与用户交互的表示层,其实是一种负责接收广播消息 并对消息作出反应的组件。在Android的系统中就存在许多这样的广播,比如电池电量过 低或信号过低时,系统就会发出广播进行通知。 应用程序如果需要响应某一个广播消息,应该注册对应的BroadcastReceiver对象, 该对象继承自BroadcastReceiver类,该类位于android.content包。这样一来当系统或 另外的应用程序发出特定广播时,该应用程序就可以接受并做出回应,如启动Activity 等。 接受广播的时候就需要通过IntentFilter对象来进行过滤。BroadcastReceiver的生 命周期比较简单,其只有一个回调方法-- onReceiver,该方法在应用程序接受到发给自己的广播的时候调用,所以BroadcastRece iver的使用方法也相对简单,只需要对onReceive方法进行合理重写,在适当的地方注册 该BroadcastReceiver即可。 注册BroadcastReceiver对象的方式有以下两种。 在AndroidMannifest.xml文件中声明。注册信息包裹在<receiver></receiver>标签 中,并在<intent-filter>标签内设定过滤规则。 在代码中创建并设置Int
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值