3Activity 1. 本章概述 本章讲解Android的组件式开发思想、Android的四大组件、Android中的Activity的基本概念、生命周期函数以及Activity之间的传值。 2. 本章重点与难点及学习方法 1) 重点 (1) Android的四大组件。 (2) Activity的生命周期。 (3) Activity的基本用法。 (4) Activity页面之间的传值。 2) 难点 (1) Activity生命周期。 (2) Activity页面之间的传值。 3. 重难点学习建议 本章将重点学习Activity的创建方法、Activity生命周期函数。理解Android程序结构及组件式开发思想,通过反复练习实践掌握Activity的用法,同时通过开发环境的Logcat观察Android生命周期函数的执行时机。 3.1Android四大组件 Android应用开发是组件式开发,所谓组件,可以理解为装修房屋的一个组成元素,一个Android应用就像一间房子,房子里的一张桌子、一把椅子、一张床就相当于Android的组件,除了这种可以直观上看得到的组件外,还有一些组件负责服务功能,例如,房子中的水管道、煤气管道、电力管道等,这些不是直接呈现在视觉中,但起着很重要的作用,就相当于Android的Service组件。要实现一个Android应用,就可以把一堆接口标准、封装完整的组件拿来用,组件搭配使用,就形成了一间装修好的房子,也就是一个Android应用了。Android的四大组件如下。 Activity: 表示一个可视化的用户界面,在应用程序中是一个单独的屏幕。每个屏幕都是通过继承和扩展基类Activity实现的。 Service: 表示服务,没有可见的用户界面,只提供服务,能够长时间运行于后台,通过继承和扩展基类Service来实现。在后台运行于应用程序进程的主线程中,因此Service不会阻塞其他组件或者用户界面。 ContentProvider: 表示内容提供者,可以将应用程序特定的数据提供给另一个应用程序使用,其数据存储方式可以是Android文件系统、SQLite数据库或者其他方式。 BroadcastReceiver: 表示广播接收器,自身并不实现图形用户界面,但是当收到某个广播后,BroadcasetReceiver可以启动Activity作为响应,或者通过NotificationManager提醒用户,或者调用Service处理长时间事务。 除了以上四大组件外,Intent 也是一个非常重要的组件,它在不同组件之间传递信息,将一个组件的请求意图传给另一个组件,可以实现组件之间调用,还可以通过Intent进行组件间传递数据。Android会根据意图的内容选择适当的组件来调用。 3.2Activity的创建 Activity的中文意思是活动,可以显示由几个View组件组成的用户接口,并且可以对事件进行相应的处理。在Android中,Activity代表手机屏幕的一屏,或是平板电脑中的一个窗口。它是Android应用程序与用户交互的窗口,几乎每一个Android应用程序都离不开Activity,它就像一个网站的页面一样,每个页面都可以通过一个独立的类来表示,这个独立的类继承于Activity这个基类。 创建Activity,大致可以分为以下两个步骤。 (1) 创建一个Activity一般是继承android.app包中的AppCompatActivity类,不过在不同的应用场景下,也可以继承Activity的子类。创建一个继承AppCompatActivity的类,名称为MainActivity的具体代码如下。import android.app.Activity; public class MainActivity extends AppCompatctivity { } (2) 重写需要的回调方法。通常情况下,都需要重写onCreate()方法,并且在该方法中调用setContentView()方法设置要显示的视图。例如,在步骤(1)中创建的Activity中,重写onCreate()方法,并且设置要显示的视图的具体代码如下。@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } 创建Activity后,还需要在AndroidManifest.xml文件中配置该Activity,具体的配置方法是在标记中添加标记实现。标记的基本格式如下。 (1) 启动Activity步骤如下。 ① 生成一个意图对象Intent。 ② 调用setClass方法设置所要启动的Activity。 ③ 调用startActivity方法启动Activity,其语句如下。public void startActivity (Intent intent) (2) 关闭Activity,其语句如下。public void finish () 3.3Activity的生命周期 在Activity的生命周期中,有表3.1所示的4个重要状态。表3.1Activity生命周期 状态描述活动状态当前Activity位于Activity栈顶,用户可见,并且可以获得焦点暂停状态失去了焦点的Activity,仍然可见,但是在内存低的情况下,它不能被系统killed(杀死)停止状态该Activity被其他Activity所覆盖,不可见,但是它仍然保存所有的状态和信息,不过,在内存低的情况下,它可能会被系统killed(杀死)销毁状态该Activity结束,或Activity所在的Dalvik进程被结束图3.1描述了Activity从创建到销毁整个生命周期方法的调用过程。 图3.1Activity的生命周期 从最初调用onCreate()到最终调用onDestroy()称为完整生命周期。Activity会在onCreate()中进行所有“全局”状态的设置,在onDestroy()中释放所有持有的资源。例如,如果它有一个从网络上下载数据的后台线程,那就可以在onCreate()中创建这个线程并在onDestroy()中停止这个线程。 从Activity调用onStart()开始,到调用对应的onStop()为止,称为可见生命周期。在这段时间内尽管此Activity并不一定是在屏幕的最前方,也不一定可以和用户交互,但是用户可以在屏幕上看到这个Activity。在这两个方法运行周期之间可以根据需求维护Activity。例如,可以在onStart()中注册一个IntentReceiver(意图接收器)来监控那些可以对UI 产生影响的环境改变,当UI 不继续在用户面前显示时,可以在onStop() 中注销这个IntentReceiver。 每当Activity 在用户面前显示或者隐藏时都会调用相应的方法,所以onStart()和onStop()方法在整个生命周期中可以多次被调用。 从Activity调用onResume()开始,到调用对应的onPause()为止称为前景生命周期,这段时间Activity处于其他所有Activity的前面,且与用户交互。一个Activity 可以经常在resumed 和paused 状态之间转换,例如,手机进入休眠时、Activity的结果返回时或者新的Intent 到来时,所以这两个方法中的代码应该非常简短。 总之,所有Activity都应该实现自己的onCreate(Bundle)方法来进行初始化设置,大部分还应该实现onPause()方法提交数据的修改,并且准备终止与用户的交互。 【例3.1】Activity生命周期回调函数执行时机练习。定义两个Activity,第一个Activity中有个标签,标签的内容为“第一个Activity”,还有一个Button,Button显示的内容为“跳到第二个Activity”,第二个Activity有一个标签,标签内容为“第二个Activity”,还有一个Button,Button显示的内容为“返回第一个Activity”。在每个Activity中添加Activity的回调函数,运行观察Logcat的输出,理解Activity各个回调函数的执行时机。 本程序需要创建两个Activity,分别为MainActivity和Main2Activity,创建Activity的步骤如下。 (1) 在使用Android项目结构时,选择Java目录下的包名,右击,在弹出的快捷菜单中选择New→Activity→Empty Activity,出现图3.2所示的对话框。 图3.2新建Activity对话框 (2) 在MainActivity类中重写Activity的几个生命周期方法,在每个方法的方法体里使用Logcat输出如下内容: 当前所在Activity名: 当前所在方法名。例如,在onRestart方法中加入如下输出语句:Log.d(TAG,"onCreate: "); 在MainActivity对应的布局文件上放置一个按钮,设置按钮的id为“go”,在后台代码中通过findViewById方法找到该按钮,设置按钮的单击事件,Android事件处理模型和Java类似,所有实现OnClickListener 接口的类,都可作为按钮事件的监听器,设置监听器的方法为setOnClickListener,每当单击按钮时,都会自动回到OnClickListener 接口的onClick方法。MainActivity对应代码如下。import android.content.Intent; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; import com.example.jason.demo20181126.R; public class MainActivity extends AppCompatActivity { //定义静态变量TAG,用于Logcat输出的标签 public static final String TAG="MainActivity"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main1); Log.d(TAG, "onCreate: "); System.out.println(); Button startActivity=(Button) findViewById(R.id.go); //设置启动按钮的监听器,匿名类作监听器 startActivity.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //使用Intent进行跳转 Intent intent=new Intent(MainActivity.this, Main2Activity.class); startActivity(intent); } }); } //重写onStart方法 @Override protected void onStart() { super.onStart(); Log.d(TAG, "onStart"); } @Override protected void onResume() { super.onResume(); Log.d(TAG, "onResume"); } @Override protected void onPause() { super.onPause(); Log.d(TAG, "onPause"); } @Override protected void onStop() { super.onStop(); Log.d(TAG, "onStop"); } @Override protected void onDestroy() { super.onDestroy(); Log.d(TAG, "onDestroy"); } @Override protected void onRestart() { super.onRestart(); Log.d(TAG, "onRestart"); } } MainActivity对应的布局文件如下。