本文为个人读书笔记,仅供记录学习过程中遇到的日后需要留意的问题,如有相关版权问题请及时通知作者。
Android应用程序可能包含的类
功能 | Java基本类 | 例子 |
用户持续聚焦的事情 | Activity | 编辑文本、玩儿游戏 |
后台进程 | Service | 播放音乐,更新天气图标 |
接受消息 | BroadcastReceiver | 根据事件触发警报 |
存储和检索数据 | ContentProvider | 打开通讯录 |
每个组件会经历了声明周期的create 创建、focus 聚焦、defocus 失去焦点和destroy 销毁。
除了ContentProvider组件,每个组件都需要一个叫做Intent的异步消息来激活。Intent可包含一组Bundle描述该组件的辅助数据。这也提供了一种在组件之间传递消息的方法。
所有的Activity均继承了抽象类Activity或它的一个子类。每个Activity的入口为onCreate()方法。通常为初始化Activity,都会对该方法进行重写,以完成设置UI、创建listener按钮监听器、初始化参数,或是启动线程一类的工作。
用户生成的文件包括:
src/ | 包含了用户为应用编写或导入的Java包。每个包可以包含多个.java文件,分别代表不同的类 |
res/layout | 包含了为每一屏截面指定布局的XML文件 |
res/values | 包含被其他文件所引用的XML文件 |
res/values-v11/ | 存放Honeycomb Android3.0~3.2 API Level 11 及更高版本设备使用的XML文件 |
res/values-v14/ | 存放Ice Cream Sandwich Android 4.0 API Level 14 及更高版本设备使用的XML文件 |
res/drawable-xhdpi/
res/drawable-hdpi/
res/drawable-mdpi/
res/drawable-ldpi/
| 包含应用在极高、高、中、低每英寸点数分辨率下所用的图片 |
assets/ | 应用要用到的非媒体文件 |
AndroidManifest.xml | 向Android系统指定该项目的特性 |
每个名为res/values-xx的文件夹下均生成有styles.xml。这是因为Android基本主题从Honeycomb版本起变为了Holo,这导致应用的主题拥有不同的父主题。
自动生成的文件包括:
gen/ | 包含了自动产生的代码,包括生成的类文件R.java |
project.properties | 含有项目设定。 |
应用程序的资源包括描述布局的XML文件、定义包括如字符串和UI元素标签等的各种值的XML文件,以及其他支持文件,比如图片和声音。编译时,对资源的引用都会收集到一个名为R.java的自动生成的wrapper class包装类中。Android Asset打包工具会自动生成该文件。
R.java中,每个资源都被映射到一个唯一的整型值。通过这种方式,R.Java提供了一种在Java代码中引用外部资源的办法。例如在Java中引用main.xml,使用整型值R.layout.main,在XML文件中,使用“@layout/main”字符串
Android项目即Android包,是Java包的集合。不同的Android包可以拥有相同的Java包名,但Android设备上安装的每个Android包的名字都应当是唯一的。
为让操作系统访问这些包,每个应用程序必须在AndroidManifest.xml文件中声明它所有可用的组件。该文件还包含运行应用所需的权限和行为。
AndroidManifest
元素 | 作用 |
application |
用户会在Android设备菜单中看到的应用程序的图标和标签。
标签是一个字符串,应当剪短
|
activity | 定义应用启动时调用的主Activity,Activity活动时title bar标题栏中显示的名称。在此需要给Java包指定名字 |
intent-filter | 向Android系统说明组件的功能,为此,它可以包含多个action、category或data。 |
uses-sdk |
定义了运行应用所需的API级别。
应该始终指定minSdkVersion的值,以确保一个应用运行在不支持其所需的特性的平台上时不会崩溃。选择可能的最低API级别
targetSdkVersion不必须指定,但指定它可以让拥有相同SDK版本的设备关闭兼容性设置,可能会提升操作速度。
|
重命名程序中的部分
Android项目 Refactor重构
Android包 Refactor重构 编辑AndroidManifest.xml文件
Android类 Refactor重构 编辑AndroidManifest.xml文件
其他文件 手动更改Java代码中相应的引用
库项目
library project库项目允许资源和代码在其他应用程序中被复用,它们也被用作UI库以使较老的设备能支持新的特性。库项目在SDK14中首次引入。库项目与一般的Android项目类似,区别在于库项目不能独立运行,无法被编译成.apk文件。
Activity的生命周期
Activity
改变屏幕方向会销毁并重建Activity
按下Home键会使Activity暂停,但不会销毁它
点击应用程序图表可能会启动一个Activity的新实例,就得Activity并未销毁的情况下也是
让屏幕休眠会暂停Activity,唤醒时会回复它,类似接电话时的情况
强制采用单任务模式
当跳出一个应用程序然后再次启动它时,可能在设备上产生同一个Activity的多个实例,为了避免这种情况,可以在AndroidManifest.xml文件中对每个Activity的此类行为进行控制。
要确保Activity只有一个实例在设备上运行,为拥有MAIN和LAUNCHER两个Intent过滤器的Activity元素内添加如下代码:
android:launchMode=“singleInstance”
这样就使任务中的每个Activity始终只有一个实例。此外,任何子Activity都会作为一个单独的任务来启动。为进一步确保应用中的所有Activity都运行在同一个任务中,使用:
android:LaunchMode=“singleTask”
为保证任务在用户返回时总是被还原到关闭之前的状态,可为任务的根Activity的activity元素指定如下属性:
android:alwaysRetainTaskState=“true”
强制规定屏幕方向
拥有加速度计的Android设备都可以判断哪个方向是下。设备从portrait纵向模式切换到landscape横向模式时,默认的动作是让应用程序的视图也随之旋转,Activity会随着屏幕方向的改变而销毁和重启。
处理屏幕变向的办法之一是在改变前保存状态信息,改变后恢复。更为简单且有用的办法是强制屏幕方向保持恒定。可以为AndroidManifest.xml文件中的每一个Activity指定screenOrientation属性。
保持纵向:
android:screenOrientation="portrait"
保持横向:
android:screenOrientation=“landscape”
只有以上代码,在硬键盘滑出时仍会引发Activity的销毁和重启。可以使用第三种方法,告诉Android系统,应用程序会处理屏幕变向和键盘滑出事件。可以通过在Activity元素中增添如下属性实现:
android:configChanges=“orientation|keyboardHidden”
该属性可以单独使用,也可与screenOrientation属性一起使用
保存和恢复Activity信息
当Activity将被杀死时,会调用onSaveInstanceState()函数。可重写该函数以保存有关信息。
当Activity被被重建时,会调用onRestoreInstanceState()函数,重写它可以恢复保存的信息。
onSaveInstanceState()有别于onPause()函数。如果另一组件被启动并置于现有Activity的前端,就会调用onPause()函数。随后当操作系统要回收资源时该Activity仍处于暂停状态,就在结束它之前调用onSaveInstanceState()
onCreate()方法同样包含Bundle savedInstanceState对象。当Activity关闭后又被重新初始化时,在onSaveInstanceState()中被保存的bundle也会被传递到onCreate()方法中。在任何情况下,被保存的bundle都要传递给onSaveInstanceState()函数,所以用它来恢复状态更为自然。
Fragment
Activity下属的小部件,用于为视图与功能分组。Fragment使得视图可以被捆绑在一起,并按需要被混合并匹配到一个或多个Activity中去。
fragment有自己的生命周期,该周期依赖于宿主Activity。Fragment拥有onPause()、onResume()、onDestroy()和onCreate()方法。
对于Fragment,onCreate(Bundle)是第二个被调用的方法,第一个调用是onAttach(Activity),它产生信号,表明已存在与宿主Activity的链接。可以在onAttach中调用Activity上的方法,但此时不能保证Activity已经将自己初始化完毕。只有当调用了onActivityCreated()方法之后,Activity才算是通过了它自己的onCreate()方法。
鉴于Fragment可以在很晚时才被实例化和添加,不应依赖Activity在onAttach()中的状态。用于初始化视图并开始大部分工作的是onCreateView(LayoutInflater,ViewGroup,Bundle)方法。如果Fragment是被重建的,那么其中的Bundle类为实现保存的实例状态。
Fragment还使用bundl来序列化参数。Fragment所需的每一种属于可打包类型的外部性信息,都可以通过调用setArguments()方法从宿主Activity获取。并且总能在Fragment中调用getArguments()方法读取它们。这使得Activity的起始Intent来的信息能够被直接传递到Fragment中显示。
多个Activity
AndroidManifes.xml中定义的主Activity会随应用程序启动而启动。该Activity可以开启另外的Activity,通常由触发事件引起。这第二个Activity被激活时,主Activity会暂停。当第二个Activity结束时,主Activity会被重新调回前台恢复运行。
要想激活应用中的某个特定组件,可以用显式命名该组件的Intent来实现。而引用程序的所需可以通过Intent过滤器指定,这时可采用隐式Intent。系统可随即确定最合适的某个或某组组件,不管它是属于另外的应用还是系统自带的。注意,与其他Activity不同,位于其他应用程序中的隐式Intent不需要在当前应用的AndroidManifest.xml文件中声明。
Android尽可能选用隐式Intent,它能为模块化功能提供强大的框架。当一个符合所需的隐式Intent过滤器要求的新组件开发完成,它就可以代替Android内部的Intent。例如:一个用来显示电话联系人的新应用被装入到Android设备,当用户选择联系人时,Android系统会找出符合浏览联系人这一Intent过滤器要求的所有可用的Activity,并询问用户想使用哪一个。