欢迎使用CSDN-markdown编辑器

来源:互联网 发布:oracle 数据库权限角色 编辑:程序博客网 时间:2024/05/19 16:07

**

Android小白的自学之路——(1)Activity生命周期理解

**
看了很多大神写的Activity详解,无疑都是从生命周期、启动模式和Intent数据传值方式这几大类写的,本人小白一枚,第一次写博客,也只是阐述一些自己的观点,无论文笔好坏都只是写了自己的理解,若有错误或者不合适的地方,还请大家能多多指教,本人在此先说句谢谢。
一般,我在拿到一个问题的时候,会形成这样一个思路:①这是什么→②能用来做什么→③产生原因是什么→④解决方式有哪些→⑤如何做出最优选择→⑥代码是否已最优化,这样做的好处在于你可以把一个很复杂的问题细节化,功能模块化,这样不仅便于理解,也有助于记忆。
如此,根据这个思路我开始讲述我学习Activity时的一些方法和一些我认为是重点的内容:
①Activity是Android四大组件之一【四大组件(Activity[活动]、Server[服务]、ContentProvider[内容提供者]、Broadcast Reciver[广播])】,是程序与用户交互的活动窗口,用大白话来讲就是你在打开一个App后看到的每个界面都是一个 Activity,它可以浮动在其他窗口之上,也可以直接铺满全屏显示。一般会默认指定一个App中的Activity为主活动,即第一个 要给用户看的界面。要设置是否是第一个给用户看一般都在AndroidManifest(清单文件)中添加意图过滤器:

<intent-filter>     <action android:name="android.intent.action.MAIN" />     <category android:name="android.intent.category.LAUNCHER" /></intent-filter>

②Activity能与用户进行实时交互,比如用户可以通过屏幕交互,比如手势,来执行拨打电话、拍摄照片、发送短信等操作, 多个彼此联系的Activity可以构成一个完整的应用,即每个Activity均可启动其他的相关的Activity。(当启动一个新的Activity 时,前一个Activity停止,失去焦点,即当前给用户展示的页面被另一个页面替代,但系统会在返回栈中保留失去焦点的 Activity,当新的Activity启动时,系统会将其推送到返回栈上,并取得用户焦点,当用户退出新的Activity时,回复前一个 Activity。)
要认识Activity那么必须知道它的生命周期,知道它是怎么运行的,为了更直观的了解,我先举个例子,比如说人的生命周期要经过:胎儿→婴儿→儿童(少年、青年、老年)→突发变故(意外)→老年→死亡,这一系列的生命过程,同样的,Activity的生命周期也会经历从创建到消亡的过程:
on Creat()[创建]→进行布局的初始化,当需要用到数据库时对数据进行绑定等操作
on Start()[可见]→当activity处于可见之前(变为在屏幕上对用户可见)调用
on Resume()[可交互/得到焦点]→即正在运行的程序且能被用户看到
on Pause()[不可交互/失去焦点]→正在运行的程序不再能被用户看到
on Stop()[不可见]→当activity处于不可见(变为在屏幕上对用户不可见)调用
on Destory()[销毁]→Activity完全被系统移除
on Restart()[重新可见]→正在运行的程序重新被用户看到
借用沙翁-博客园的一张图来深入了解:
这里写图片描述
七个生命周期组合:
onCreate、onStart、onResume:启动应用程序
onPause、onStop:失去焦点
onRestart、onStart、onResume:重新获得焦点
onPause、onStop、onDestroy :退出应用程序
七个生命周期按阶段划分:
onCreate() — onDestroy() 完整生命周期 The entire lifetime
onStart() — onStop() 可见生命周期 The visible lifetime
onResume() — onPause() 前沿生命周期(焦点生命周期) The foreground lifetime
定义生命周期的作用:
①当用户接一个电话或切换到另一个程序不会崩溃
②当用户后台运行程序时不会销毁有价值的系统资源
③当用户离开再返回你的应用时不会丢失用户的进程
④当手机屏幕进行横竖屏切换的时候不会崩溃或者丢掉用户的进程
例如:模仿以下操作,观察输出日志,发现生命周期方法依次回调的规律:
1.打开主界面,后退键退出
2.打开主界面,进入第二个页面
3.打开主界面,模拟电话进入及挂机再次显示主界面
4.打开主界面,HOME键退出
5.打开主界面,HOME键退出,再次启动app
6.打开主界面,点击该界面中捆绑退出事件的按钮后退出
7.打开主界面,切换横屏竖屏。

 I/MainActivity(741): ==MainActivity onCreate   执行了 I/MainActivity(741): ==MainActivity onStart    执行了 I/MainActivity(741): ==MainActivity onResume   执行了 I/MainActivity(741): ==MainActivity onPause    执行了 I/MainActivity(741): ==MainActivity onStop     执行了 I/MainActivity(741): ==MainActivity onDestroy  执行了 I/MainActivity(741): ==MainActivity onCreate   执行了 I/MainActivity(741): ==MainActivity onStart    执行了 I/MainActivity(741): ==MainActivity onResume   执行了

模拟Android音乐播放器,练习Activity生命周期的示例代码:

publicclass MainActivity extends Activity {privatestaticfinal String TAG = "MainActivity";privatestaticinti = 0;private Button button_main_play;private Timer timer = null;privatebooleanflag = false;// 设置flag标记位的目的是避免程序一开启就执行,而是等点击了按钮后才开始。@Overrideprotectedvoid onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);button_main_play = (Button) findViewById(R.id.button_main_play);button_main_play.setOnClickListener(new OnClickListener() {@Overridepublicvoid onClick(View v) {// 点击按钮后执行播放playMusic();// 设置flag标记位的目的是避免程序一开启就执行。现在点击了按钮,允许程序在再次执行的时候自动执行。flag = true;}});}@Overrideprotectedvoid onStart() {super.onStart();}@Overrideprotectedvoid onResume() {super.onResume();// 默认flag为false,不允许自动执行,而是当点击了播放后才允许执行。if (flag) {playMusic();}}@Overrideprotectedvoid onPause() {super.onPause();// 当有电话进入,会回调onPause()方法,这个时候要让播放器停止。// 定时器timer对象的cancel()方法能取消定时器。timer.cancel();}@Overrideprotectedvoid onStop() {super.onStop();}@Overrideprotectedvoid onRestart() {super.onRestart();}@Overrideprotectedvoid onDestroy() {super.onDestroy();// 如果希望程序退出后,下次运行从头开始播放,可以将进度初始化为0.// 如果点HOME退出,程序没有完全退出,下次播放应该从上次的进度继续执行。所以不应该初始化。// 所以将初始化写在onDestroy(),而不写在onStop()中。(因为点HOME退出不会回调onDestroy()方法。)i = 0;}@Overridepublicboolean onCreateOptionsMenu(Menu menu) {getMenuInflater().inflate(R.menu.main, menu);returntrue;}publicvoid playMusic() {// 用定时器输出数字来模拟播放器播放的效果timer = new Timer();// 定时器timer对象的sechedule()方法有三个参数,第一个表示定时执行的任务,第二个参数表示延迟时间,第三个参数表示间隔的时间timer.schedule(new TimerTask() {@Overridepublicvoid run() {Log.i(TAG, "==i=" + i);i++;}}, 0, 1000);}}

由于第一次发博文,不知道怎么上传代码,所以只能写成代码片的形式,代码可读性不好,请大家见谅,文章不足之处我后续还会改进,还请多多指教,谢谢大家。

1 0