android知识1-Activity

来源:互联网 发布:中国象棋训练软件 编辑:程序博客网 时间:2024/05/20 15:37

转眼从事安卓开发快两年了,感觉时间越长越觉得自己知识浅薄,长久以来持续的copy改让我自己开始觉得惭愧,学到现在连基本的自定义view都写不好。。现在想回过头来把自己了解到的所有基础知识点再巩固一下。我不想从头到尾的去写一本基础教程(我可能也没有这个时间和实力),这一系列文章只是自己的笔记,也就是在这里不会介绍我认为很基础的东西,这里只是记录我认为的一些易错点和难点。看到别人都开始写各种高级文章了,我还停留在复习(甚至是预习)安卓的老本行上面。。

关于Activity基础用法的知识点我想记录以下几个方面的内容:

activity生命周期和数据恢复

activity启动模式

activity的intentfilter如何匹配
activity的startActivityForIntent方法以及Android6.0以上的requestPermissions

- Activity的生命周期及数据恢复

常规生命周期:在Activity的合适的生命周期做合适的处理是最基础的,Activity在第一次创建会执行onCreate-onStart-onResume。切入后台(完全不可见)会执行onPause-onStop。在此切换到前台会执行onRestart-onStart-onResume。退出Activity会执行onPause-onStop-onDestroy。onStop方法并不总是执行的,onStop表示切入后台(完全不可见),例如打开一个dialog主题的Activity或者背景是透明的Activity(未验证)则只触发onPause,所以如果需要可靠的执行一些操作应该是在onPause中执行的,但是onPause中不可以做大量的耗时工作,因为启动新的activity是需要等待旧Activity的onPause执行完才会执行新Activity的onCreate方法的。onDestroy方法在用户强制结束的时候不会执行(后台Service的onDestory也不会执行)。对应关系为onCreate-onDestroy,onStart-onStop, onResume-onPause.
Activity数据恢复:安卓生命周期之外还有一个很重要的方法就是onSaveInstanceState (Bundle outState),当当前Activity有可能被销毁,并且在后续需要重新恢复数据显示的时候该方法会被系统回调,常见的有后台运行的Activity由于内存不足被回收之前、横竖屏切换导致Activity被重新创建之前。可以在outState中保存键值对,然后再在 onCreate(Bundle) 或者onRestoreInstanceState(Bundle)中拿到bundle对象恢复保存的数据,在onCreate携带的bundle可以为null表明第一次创建,而onRestoreInstanceState(Bundle)的bundle一定不是null,onRestoreInstanceState调用时机是onStart之后, onStart() 和onPostCreate(Bundle)之间,onResume之前。

tips:如果需要组织旋转屏幕导致Activity重新创建,可以在activity标签下加入

android:configChanges="orientation/screenSize"

- Activity启动模式

activity有四种启动模式standard/singleTop/singleTask/singleInstance,在AndroidManifest中用用android:launchMode来定义。关于四种模式的文字定义不再赘述,理解四种模式的关键在于理解任务栈。
一个应用程序默认有一个任务栈,按back返回其实就是不断出栈的结果,当任务栈为空了就退出了应用。任务栈可以分为处于前台可以和用户交互的任务栈和处于后台运行但是不和用户交互的任务栈,每个Activity都必须有自己的任务栈,默认是存放在调用者(此处指Activity,如果是Service或者Application等Activity之外的上下文需要添加FLAG_ACTIVITY_NEW_TASK标记位,表示创建新的任务栈来存放)的任务栈里的,当然也可以用android:taskAffinity声明Activity要存放的任务栈。当定义为singleTop的Activity处于栈顶被在此请求调用时或者singletask的Activity在栈中存在了又被在此请求调用时,Activity不会重新创建,而是只执行onNewIntent(Intent intent) 方法(在第一次创建时不会调用onNewIntent),然后会执行onResume方法。关于onNewIntent谷歌有如下提示

Note that getIntent() still returns the original Intent. You can use setIntent(Intent) to update it to this new Intent.

还有一点就是taskAffinity和android:allowTaskReparenting配合使用的时候可以转移Activity到taskAffinity的任务栈中,类似QQ分享消息滞后,再回到桌面点开QQ还在分享界面,显然Activity是换了任务栈了,不是再存在其调用者的任务栈中了。

- intentfilter匹配规则

intent-filter标签用于activity、service、broadcast的隐式启动,是可以跨进程接收响应的,主要使用action、data、category三个标签共同定义父组件可以响应的intent。附上谷歌的解释文档:

https://developer.android.com/guide/topics/manifest/intent-filter-element.html

一个activity(或者service、broadcast,以下都只写activity了)可以包含多个intent-filefer标签,每个intent-filter都至少需要包含一个action标签,category和data标签可以有0个或者多个,并且可以定义icon、label、priority等内容。只有action、data、category同时匹配成功的才算能够响应。
action部分:一个intent只有一个action,如果这个action恰好在intent-filter中有定义那么action就算匹配。
data部分:声明data标签表示附加action之外额外的条件来判定匹配。一个intent只有一个data类型和uri,如果定义了data标签,则只有这个itent的uri和mimeType和某一个data标签定义的均相符合,那么data就算匹配了。类型表示能够打开哪些类型,uri我理解为对路径的限定。附上android4.4的mimeType列表。
category:一个intent可以包含多个category,只有这多个category都能再同一个intent-filter中找到才算category匹配成功,安卓在startactivity和startActivityForResult的时候会附加”android.intent.category.DEFAULT”这个Category,所以如果想要相应隐式启动,你必须要显式的为你的组件添加上这个默认的Category。

//以下表示,桌面上显示应用图标,并且这个activity是程序的入口activity<action android:name="android.intent.action.MAIN" />    <category android:name="android.intent.category.LAUNCHER" />

可以参考下这位大神写的,很清晰:
http://blog.csdn.net/mynameishuangshuai/article/details/51673273

- startActivityForResult以及requestPermissions

startActivityForResult用来启动另一个Activity并等待其关闭时返回给自己值时使用,例如拍照。类似的有requestPermissions用来在android6.0以上动态的申请权限。官网介绍的很详细。
https://developer.android.com/training/basics/intents/result.html#StartActivity
https://developer.android.com/training/permissions/requesting.html

原创粉丝点击