Android学习笔记 ( by quqi99 )
Posted quqi99
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android学习笔记 ( by quqi99 )相关的知识,希望对你有一定的参考价值。
Android 学习笔记 ( by quqi99 )
作者:张华 发表于:2007-12-04 ( http://blog.csdn.net/quqi99 )
版权声明:可以任意转载,转载时请务必以超链接形式标明文章原始出处和作者信息及本版权声明。
版权声明:可以任意转载,转载时请务必以超链接形式标明文章原始出处和作者信息及本版权声明。
(注:有些内容来自
http://www.androidcn.net )
android platform是一个用于开发移动程序的软件包,它包括了操作系统、中间件及一些关键应用。开发者能使用android SDK为Android platform开发应用,这些应用使用JAVA语言书写,运行在虚拟机Dalvik(一个专为手机程序开发的基于linux内核的JAVA虚拟机)。
1 什么是 Android
1.1 Android 的特性
ü 应用框架,让一些基础设施得以重用
ü Dalvik虚拟机,专为开发移动程序优化
ü 集成的浏览器,(基于WebKit引擎)
ü 优化的图形库,(2D图形库以及基于
OpenGL ES 1.0
规范的
3D
图形库)
ü
SQLite
,用于结构化数据的存储,是一个数据库
ü
多媒体支持,支持多种音频,视频格式(
MPEG4, H.264, MP3, AAC, AMR, JPG, PNG, GIF
)
ü
GSM
技术(依赖具体硬件)
ü
Bluetooth, EDGE, 3G, WiFi
(依赖具体硬件)
ü
Camera, GPS, compass, accelerometer
(依赖具体硬件)
ü 丰富的开发环境(DEBUG工具,内存及性能工具,Eclipse的插件等)
1.2 Android 的架构
Android 操作系统的模块如下:
Ø 应用:Android已集成了一些应用,如邮件客户端,SMS程序,日历,地图,浏览器等
Ø 应用框架:
Ø 程序库:
Ø 例行程序
Ø Linux内核
2 Andvoid 起步
2.1 开发环境配置
使用Eclipse +
Android Development Tools (ADT)
插件。在
Help
> Software Updates > Find and Install... .
中键入更新地址:
2.2 运行第一个 Andvoid 程序
使用
Eclipse
插件
1 、建立的工程类型为:Andvoid Project
2 、建立Launch Configuration.
Run
> Open Run Dialog... or Run > Open Debug Dialog
命令行运行程序
1
、创建工程 activityCreator your.package.name.ActivityName
2、编译。在build.xml所在的目录ant一下。
3、启动模拟器. 运行命令:emulator
4、在模拟器中,切换到主屏幕。
5、在命令行输入: adb install myproject/bin/<appname>.apk将其上载至模拟器。
6、在模拟器中选择程序并启动。
Android需要专门的编译工具来正确的编译资源文件和Android程序的其他部分。基于此,你需要为你的程序准备一个专门的编译环境。
Andorid的编译过程通常包括编译XML和其他资源文件、创建正确的输入格式。经过编译的Android程序是一个.apk文件,.apk文件是一个压缩文件,它其中包含了.dex文件、资源文件、raw data文件和其他文件。
Andoriod暂时还不支持用本地代码(C/C++)开发第三方程序。
移除
Andorid
程序
要移除你安装在模拟器上的程序,你需要通过run adb 并删除相应的.apk文件。通过adb shell命令在模拟器上打开一个UNIX shell,进入目录data/app/,通过命令rm 你程序的名称.apk来移除文件。
2.3 调试程序
Andvoid用于调试的手段有:
DDMS,DDMS是一个图形化的程序,支持端口转发(因此你可以在程序中设置断点),支持模拟器上的截屏,支持线程和堆栈信息和其他的一些特性。
Logcat,Dump一份系统消息的日志。这些消息包括模拟器抛出错误时的堆栈跟踪。
Android Log, 打印日志的类,用来将消息写入模拟器上的日志文件中。如Log.v()用于打印verbose级别的日志
Traceview,Android可以保存一个日志用来记录被调用的方法以及该方法被调用的次数,通过Traceview你可以在一个图形化的界面中查看这个日志文件。
可接解设置emulator的设置以方便调试,
模拟器上调试和测试的设置
Android
提供了众多的设置使你可以更容易的调试和测试程序。要进入开发设置页面,在模拟器中转到Dev Tools > Development Settings 。在该设置页面有以下选项:
- Debug app :选择要调试的程序。你不需要设定其关联至调试器,但是设定这个值有两个效果:
- 在调试的时候,如果你在一个断点处暂停了过长的时间,这个设定会防止Android抛出一个错误
- 这个设定使你可以选择“等待调试器”选项,使程序只有在调试器关联上之后才启动
- Wait for Debugger :阻塞所选的程序的加载直到有调试器关联上,这样你就可以在onCreate()中设置断点,这对于调试一个Activity的启动进程是非常重要的。当你对该选项进行了更改,任何正在运行的程序的实例都会被终止。你只有在上面的选项中选择了一个调试程序才能够选中该选项。你一也可以在代码中添加waitForDebugger() 来实现同样的功能。
- Immediately destroy activities :告诉系统一旦一个activity停止了就销毁该activity(例如当Android释放内存的时候)。这对于测试代码onFreeze(Bundle) /onCreate(android.os.Bundle) 是非常有用的,否则会比较困难。如果你的程序没有保存状态,那么选择这个选项很可能会引发很多问题。
- Show screen updates :对于任何正在被重绘的screen sections都会在其上闪现一个粉红色的矩形。这对于发现不必要的screen绘制是很有必要的。
- Show CPU usage :在屏幕上方显示CPU信息,显示有多少CPU资源正在被使用。上方红色条显示总的CPU使用率,它下方绿色的条显示CPU用在compositing the screen上的时间。注意:在没有重启模拟器之前,一旦你开启了该功能就不能关闭。
- Show screen FPS :显示当前的帧率。这对于查看游戏达到的总的帧率是非常有用的。注意:在没有重启模拟器之前,一旦你开启了该功能就不能关闭。
- Show background :当没有activity screens可见时,显示一个背景模式。一般是不会出现的,仅仅在Debug的时候会出现。
设定的选项在模拟器重启之后仍然有效,如果要取消设定的选项,在取消设定以后还要重启模拟器,才能生效。
2.4 andvoid 中的概念
一个andvoid应用包括四个部分:
n Activity活动
(个人认为 :类似于JSP, 也相当于SWT中的Shell, View则相当于wegiet)
n Intent Receiver (个人认为 :类似于Struts action)
n Service
(个人认为 :类似于Servlet)
n Content Provider (个人认为 :用于持久化)
用上面哪些组件,要在
AndroidManifest.xml
文件中声明。
1、
Activity.
一个
activity
是应用中的一个单一的屏幕,它继承自
Activity
类,它将显示由
Views
组成的
UI
以及响应事件。(个人理解,相当于
JSP
)
2、
Intent
与
Intent Filters. Intent
用于从一个屏幕跳到别一个屏幕,描述一个应用想做什么,它的数据结构包括
action
与
data
两部分,它是一个消息操作对象,一个被动的数据结构。
action
如
MAIN
、
VIEW
、
PICK
、
EDIT
等等
, data
被表达成一个
URI
;
IntentFilter
相当于告诉跳到哪个
activity,
;
IntentReceiver
用于响应事件,虽然它不显示
UI
,但它可以用
NotificationManager
去通知用户。它需要在
AndroidManifest.xml
文件中注册,或者是用
Context.registerReceiver()
硬编码。
3、
Service
是一段有生命周期的无
UI
的代码。
4、
Content Provider,
持久化,例如存储在文件系统中,或者存储在
SQLite
数据库中。
2.5 例子
例如:Notepadv1工程是问题工程,Notepadv1Solution则是相应的解决工程。
2 ,3个例子的函义如下:
通过练习
1>
1. 数据库对象的例子程序
2. 如何在一个Activity初始化的时候创建数据库对象
3. 如何为一个Activity创建一个pop菜单
4. 如何得到一个用户在POP菜单中选择的ITEM 的ID
5. 如何向一个ListView中写入数据
1. 数据库对象的例子程序
2. 如何在一个Activity初始化的时候创建数据库对象
3. 如何为一个Activity创建一个pop菜单
4. 如何得到一个用户在POP菜单中选择的ITEM 的ID
5. 如何向一个ListView中写入数据
通过练习
2>
1. 如何取得数据集中被选择数据行的ID, 注意rows是java的一个listarray对象,所以它有它的getSelection()的方法
2. 如何调用一个SubActivity以及在调用一个SubActivity之前应该做些事情。
3. 要实现一个方法, 当SubActivity返回后,应该做些什么
4. 关于layout。由于Android采用MVC的模式, 所以屏幕的布局采用了XML进行定义。一个好的布局会让程序显的更漂亮。可以参考 http://code.google.com/android/reference/view-gallery.html , 有很多的布局模式可供利用。
5. 如何创建一个开始的时候代码中不含onCreate()的类,因为到目前为止还没有创建过自己的类,以前看到的类和修改的方法都是已经写好的了。不过这个类也是一个从android.app.Activity继承的。创建后还是要通过Source Override一个onCreate的
6. 从一个SubActivity返回时,在返回之前应该做哪些事情
7. 如何在AndroidManifest.xml中声明一个新的Activity
8. 如何创建一个内部隐含的onClickLister及实现其应有的功能。
1. 如何取得数据集中被选择数据行的ID, 注意rows是java的一个listarray对象,所以它有它的getSelection()的方法
2. 如何调用一个SubActivity以及在调用一个SubActivity之前应该做些事情。
3. 要实现一个方法, 当SubActivity返回后,应该做些什么
4. 关于layout。由于Android采用MVC的模式, 所以屏幕的布局采用了XML进行定义。一个好的布局会让程序显的更漂亮。可以参考 http://code.google.com/android/reference/view-gallery.html , 有很多的布局模式可供利用。
5. 如何创建一个开始的时候代码中不含onCreate()的类,因为到目前为止还没有创建过自己的类,以前看到的类和修改的方法都是已经写好的了。不过这个类也是一个从android.app.Activity继承的。创建后还是要通过Source Override一个onCreate的
6. 从一个SubActivity返回时,在返回之前应该做哪些事情
7. 如何在AndroidManifest.xml中声明一个新的Activity
8. 如何创建一个内部隐含的onClickLister及实现其应有的功能。
通过练习
3>
1. 除了onCreate()还有哪些和lifecycle有关的方法
a.onFreeze():
b.onPause()
c.onResume()
等等…
2. 大部分程序都有必要考虑lifecycle的问题,应该把下面的这个图记住:
3. 为了不丢失需要保存的信息,要明确的理解Activity的各个状态,并相应的给出在各个状态的行为。
4.开始的时候对于onFreeze()和onPause()有些理解上的困难,要多读几遍DOC来会理解。 通过额外练习 >
1. 除了onCreate()还有哪些和lifecycle有关的方法
a.onFreeze():
b.onPause()
c.onResume()
等等…
2. 大部分程序都有必要考虑lifecycle的问题,应该把下面的这个图记住:
3. 为了不丢失需要保存的信息,要明确的理解Activity的各个状态,并相应的给出在各个状态的行为。
4.开始的时候对于onFreeze()和onPause()有些理解上的困难,要多读几遍DOC来会理解。 通过额外练习 >
进一步的理解lifecycle和通过手机按键进行操作时的时间和程序状态关系
另外,SDK目录下也有一些例子。
练习目标:
1. 使用 ListActivities ,并使用菜单
2. 学习使用操作 SQLite 数据库
3. 使用 ArrayAdapter 绑定数据到 ListView 中
4. 掌握一些基本的操作,如菜单的显示,菜单命令的处理,增加数据项等。
1. 使用 ListActivities ,并使用菜单
2. 学习使用操作 SQLite 数据库
3. 使用 ArrayAdapter 绑定数据到 ListView 中
4. 掌握一些基本的操作,如菜单的显示,菜单命令的处理,增加数据项等。
第一步 :
在SDK中下载获得Notepadv1的代码,并导入到Eclipse中。导入步骤:
a. 在Package Explorer中,右键选择Import.../General/Existing Projects into Workspace
b. 点Browse按钮,选择Notepadv1 的目录,并点OK
c. 你将会看到Notepadv1被列在项目区中,默认会被打勾,如果没有打勾,请手动勾上。
d. 点Finish
e. Notepadv1将被列在Package Explorer中
f. 如果有提示关于AndroidManifest.xml的错误,请选中此项目,并右键选择Android Tools->Fix Project ,他将会自动帮你修复错误。
在SDK中下载获得Notepadv1的代码,并导入到Eclipse中。导入步骤:
a. 在Package Explorer中,右键选择Import.../General/Existing Projects into Workspace
b. 点Browse按钮,选择Notepadv1 的目录,并点OK
c. 你将会看到Notepadv1被列在项目区中,默认会被打勾,如果没有打勾,请手动勾上。
d. 点Finish
e. Notepadv1将被列在Package Explorer中
f. 如果有提示关于AndroidManifest.xml的错误,请选中此项目,并右键选择Android Tools->Fix Project ,他将会自动帮你修复错误。
第二步
:
看一下数据库操作类: DBHelper ,还是比较简单的,自己看去 :) 。
看一下数据库操作类: DBHelper ,还是比较简单的,自己看去 :) 。
第三步
:
打开 res/layout/notepad_list.xml 这个文件,快速的看下就可以了:
a.<?xml version="1.0" encoding="utf-8"?> , XML 文件的固定头
打开 res/layout/notepad_list.xml 这个文件,快速的看下就可以了:
a.<?xml version="1.0" encoding="utf-8"?> , XML 文件的固定头
b.
一个
Layout
的定义,这里是
LinearLayout
,但不一定是这个,可以是其他的
Layout
第四步
:
在上面的那个文件中加入:
<ListView id="@id/android:list"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView id="@id/android:empty"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/no_notes"/>
在上面的那个文件中加入:
<ListView id="@id/android:list"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView id="@id/android:empty"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/no_notes"/>
a. ListView
和
TextView
不会同是显示,如果没有数据,则默认显示
TextView
(这个
View
里会显示一个字符串)。如果有数据,则会显示
ListView
。
b.@ 是默认的关键字, XML 解析器将会自动替换这个符号后面的 ID
c.android:list 和 android:empty 是 android 平台预定义好的 ID ,如果你想显示空的 TextView ,可以调用 setEmptyView().
b.@ 是默认的关键字, XML 解析器将会自动替换这个符号后面的 ID
c.android:list 和 android:empty 是 android 平台预定义好的 ID ,如果你想显示空的 TextView ,可以调用 setEmptyView().
第五步:
建立一个新文件 res/layout/notes_row.xml ,文件内容如下:
<?xml version="1.0" encoding="utf-8"?>
<TextView id="@+id/text1"
xmlns:android="http://schemas.android.com/apk/res/android "
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
建立一个新文件 res/layout/notes_row.xml ,文件内容如下:
<?xml version="1.0" encoding="utf-8"?>
<TextView id="@+id/text1"
xmlns:android="http://schemas.android.com/apk/res/android "
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
然后保存,
R.java
下将会自动刷新。
第六步
改变继承类
public class Notepadv1 extends ListActivity
改变继承类
public class Notepadv1 extends ListActivity
第七步:
看一下这三个事件:
onCreate() :界面初始化的时候调用
onCreateOptionsMenu() :按了 Menu 按钮的时候调用
onOptionsItemSelected() :选择了一个菜单项的时候调用
看一下这三个事件:
onCreate() :界面初始化的时候调用
onCreateOptionsMenu() :按了 Menu 按钮的时候调用
onOptionsItemSelected() :选择了一个菜单项的时候调用
第八步
:
改写 OnCreate 函数:
private DBHelper dbHelper;
改写 OnCreate 函数:
private DBHelper dbHelper;
@Override
public void onCreate(Bundle icicle)
{
super.onCreate(icicle);
setContentView(R.layout.notepad_list);
dbHelper = new DBHelper(this);
fillData();
}
public void onCreate(Bundle icicle)
{
super.onCreate(icicle);
setContentView(R.layout.notepad_list);
dbHelper = new DBHelper(this);
fillData();
}
第九步:
在 strings.xml 中增加: <string name="menu_insert">Add Item</string>
并在
Notepadv1
类中加入:
public static final int INSERT_ID = Menu.FIRST;
改写
onCreateOptionsMenu()
@Override
public boolean onCreateOptionsMenu(Menu menu) {
boolean result = super.onCreateOptionsMenu(menu);
menu.add(0, INSERT_ID, R.string.menu_insert);
return result;
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
boolean result = super.onCreateOptionsMenu(menu);
menu.add(0, INSERT_ID, R.string.menu_insert);
return result;
}
第十步:
改写 onOptionsItemSelected()
@Override
public boolean onOptionsItemSelected(Item item) {
switch (item.getId()) {
case INSERT_ID:
createNote();
break;
}
return super.onOptionsItemSelected(item);
}
第十一步:
实现两个函数:
private void createNote() {
String noteName = "Note " + noteNumber++;
dbHelper.createRow(noteName, "");
fillData();
}
实现两个函数:
private void createNote() {
String noteName = "Note " + noteNumber++;
dbHelper.createRow(noteName, "");
fillData();
}
private void fillData() {
// We need a list of strings for the list items
List<String> items = new ArrayList<String>();
// We need a list of strings for the list items
List<String> items = new ArrayList<String>();
// Get all of the rows from the database and create the item list
List<Row> rows = dbHelper.fetchAllRows();
for (Row row : rows) {
items.add(row.title);
}
// Now create an array adapter and set it to display using our row
ArrayAdapter<String> notes =
new ArrayAdapter<String>(this, R.layout.notes_row, items); // 指定notes_row视图,作为数据容器。
setListAdapter(notes);
}
List<Row> rows = dbHelper.fetchAllRows();
for (Row row : rows) {
items.add(row.title);
}
// Now create an array adapter and set it to display using our row
ArrayAdapter<String> notes =
new ArrayAdapter<String>(this, R.layout.notes_row, items); // 指定notes_row视图,作为数据容器。
setListAdapter(notes);
}
第十二步:
运行: Run As -> Android Application
运行: Run As -> Android Application
2.6 开发工具
2.6.1 仿真器
仿真器是在计算机中运行的一个虚拟的移动装置,用它来设计、调试应用。
2.6.2 A DT
ADT是一个用于开发andvoid应用的确良eclipse插件,它方便了我们的开发。例如,它让我们方便从eclipse内部访问DDMS工具(可用于截屏,管理port-forwarding,设断点,查看线程和进程信息)
2.6.3 DDMS
DDMS(Dalvik Debug Monitor Service)和Dalvik虚拟机集成,将在IDE和模拟器起到一个转发服务。用它能管理仿填器或者设备的进程,并且辅助调试。你可用它杀死进程,选择某一进程去DEBUG,产生TRACE数据,查看堆和线程信息等等。
2.6.4 A DB
ADB(Andvoid Debug Bridge)。在命令行操作。它能安装.apk文件到仿真器上等等。用于将文件发送到仿真器。adb(Android Debug Bridge)是Android提供的一个通用的调试工具,借助这个工具,我们可以管理设备或手机模拟器的状态。还可以进行以下的操作:
1
、快速更新设备或手机模拟器中的代码,如应用或Android系统升级;
2
、在设备上运行shell命令;
3
、管理设备或手机模拟器上的预定端口;
4
、在设备或手机模拟器上复制或粘贴文件;
以下为一些常用的操作:
1
、安装应用到模拟器:
adb install
比较郁闷的是,Android并没有提供一个卸载应用的命令,只能自己手动删除:
adb shell
cd /data/app
rm app.apk
2
、进入设备或模拟器的shell:
adb shell
通过上面的命令,就可以进入设备或模拟器的shell环境中,在这个Linux Shell中,你可以执行各种Linux的命令,另外如果只想执行一条shell命令,可以采用以下的方式:
adb shell [command]
如:adb shell dmesg会打印出内核的调试信息。
3
、发布端口:
你可以设置任意的端口号,做为主机向模拟器或设备的请求端口。如:
adb forward tcp:5555 tcp:8000
4
、复制文件:
你可向一个设备或从一个设备中复制文件,
复制一个文件或目录到设备或模拟器上:
adb push
如:adb push test.txt /tmp/test.txt
从设备或模拟器上复制一个文件或目录:
adb pull
如:adb pull /addroid/lib/libwebcore.so .
5
、搜索模拟器/设备的实例:
取得当前运行的模拟器/设备的实例的列表及每个实例的状态:
adb devices
6
、查看bug报告:
adb bugreport
7
、记录无线通讯日志:
一般来说,无线通讯的日志非常多,在运行时没必要去记录,但我们还是可以通过命令,设置记录:
adb shell
logcat -b radio
8
、获取设备的ID和序列号:
adb get-product
adb get-serialno
9
、访问数据库SQLite3
adb shell
sqlite3
2.6.5 a apt
Aapt(Andvoid Asset Packaging Tool) ,用于创建.apk文件。
2.6.6 a idl
Aidl(Andvoid Interface Description Language)用于产生代码。
2.6.7 sqlite3
用于访问SQLite数据文件。
2.6.8 Traceview
查看LOG信息
2.6.9 mksdcard
Helps you create a disk image that you can use with the emulator, to simulate the presence of an external storage card (such as an SD card
2.6.10 dx
Dx工具用于重写.class字节码到Andvoid字节码
2.6.11 a ctivityCreator
用于产生ant文件的脚本。当然,若用eclipse插件就不需要它了。
2.7 Andvoid 应用的生命周期
在大部份情况下,每个Android应用都将运行在自己的Linux进程当中。当这个应用的某些代码需要执行时,进程就会被创建,并且将保持运行,直到该进程不再需要,而系统需要释放它所占用的内存,为其他应用所用时,才停止。
Android一个重要并且特殊的特性就是,一个应用的进程的生命周期不是由应用自身直接控制的,而是由系统,根据运行中的应用的一些特征来决定的,包括:这些应用对用户的重要性、系统的全部可用内存。
对于应用开发者来说,理解不同的应用组件(特别是Activity、Service、Intent Receiver)对应用进程的生命周期的影响,这是非常重要的。如果没有正确地使用这些组件,将会导致当应用正在处理重要的工作时,进程却被系统消毁的后果。
对于进程生命周期,一个普遍的错误就是:当一个Intent Receiver在它的onReceiveIntent()方法中,接收到一个intent后,就会从这个方法中返回。而一旦从这个方法返回后,系统将会认为这个Intent Receiver不再处于活动状态了,也就会认为它的宿主进程不需要了(除非宿主进程中还存在其它的应用组件)。从而,系统随时都会消毁这个进程,收回内存,并中止其中还在运行的子线程。问题的解决办法就是,在IntentReceiver中,启动一个Service,这样系统就会知道在这个进程中,还有活动的工作正在执行。
为了决定在内存不足情况下消毁哪个进程,Android会根据这些进程内运行的组件及这些组件的状态,把这些进程划分出一个“重要性层次”。这个层次按顺序如下:
1、前端进程是拥有一个显示在屏幕最前端并与使用者做交互的Activity(它的onResume已被调用)的进程,也可能是一个拥有正在运行的IntentReceiver(它的onReceiveIntent()方法正在运行)的进程。在系统中,这种进程是很少的,只有当内存低到不足于支持这些进程的继续运行,才会将这些进程消毁。通常这时候,设备已经达到了需要进行内存整理的状态,为了保障用户界面不停止响应,只能消毁这些进程;
2、可视进程是拥有一个用户在屏幕上可见的,但并没有在前端显示的Activity(它的onPause已被调用)的进程。例如:一个以对话框显示的前端activity在屏幕上显示,而它后面的上一级activity仍然是可见的。这样的进程是非常重要的,一般不会被消毁,除非为了保障所有的前端进程正常运行,才会被消毁。
3、服务进程是拥有一个由startService()方法启动的Service的进程。尽管这些进程对于使用者是不可见的,但他们做的通常是使用者所关注的事情(如后台MP3播放器或后台上传下载数据的网络服务)。因此,除非为了保障前端进程和可视进程的正常运行,系统才会消毁这种进程。
4、后台进程是拥有一个用户不可见的Activity(onStop()方法已经被调用)的进程。这些进程不直接影响用户的体验。如果这些进程正确地完成了自己的生命周期(详细参考Activity类),系统会为了以上三种类型进程,而随时消毁这种进程以释放内存。通常会有很多这样的进程在运行着,因些这些进程会被保存在一个LRU列表中,以保证在内存不足时,用户最后看到的进程将在最后才被消毁。
5、空进程是那些不拥有任何活动的应用组件的进程。保留这些进程的唯一理由是,做为一个缓存,在它所属的应用的组件下一次需要时,缩短启动的时间。同样的,为了在这些缓存的空进程和底层的核心缓存之间平衡系统资源,系统会经常消毁这些空进程。
当要对一个进程进行分类时,系统会选择在这个进程中所有活动的组件中重要等级最高的那个做为依据。可以参考Activity、Service、IntentReceiver文档,了解这些组件如何影响进程整个生命周期的更多细节。这些类的文档都对他们如何影响他们所属的应用的整个生命周期,做了详细的描述。
2 开发应用
2.1 前端 UI
2.1.1 . 屏幕元素的层次
1. Views
一个View是android.view.View基础类的一个对象,它是一个有屏幕上特定的一个矩形内布局和内容属性的数据结构。一个View对象处理测量和布局,绘图,焦点变换,滚动条,还有屏幕区域自己表现的按键和手势。
View类作为一个基类为widget(窗体部件)服务,widget--是一组用于绘制交互屏幕元素的完全实现子类。Widget处理它们自己的测距和绘图,所以你可以更快速地用它们去构建你的UI。可用到的widget包括
Text
,
EditText
,
InputMethod
,
Button
,
RadioButton
,
Checkbox
,和
ScrollView 。
2. Viewgroups
一个ViewGroup是一个android.view.Viewgroup类的对象。一个viewgroup是一个特殊的view对象,它的功能是去装载和管理一组下层的view和其他viewgroup,Viewgroup让你可以为你的UI增加结构并且将复杂的屏幕元素构建成一个独立的实体。
Viewgroup类作为一个基类为layout(布局)服务,layout--是一组提供屏幕界面通用类型的完全实现子类。layout让你可以为一组view构建一个结构。
3. A Tree-Structured UI
在Android平台上,你用view树和viewgroup节点来定义一个Activity的UI,就如同下面图表一样。这个树可以如你需要那样简单或者复杂,并且你可以使用Android的预定义widget和layout或者你自定义的view类型来构建它。
要将屏幕绑定一个树以便于渲染,你的Activity调用它的setContentView()方法并且传递一个参数给根节点对象。一旦Android系统获得了根节点的参数,它就可以直接通过节点来无效化,测距和绘制树。
当你的
Activity
被激活并且获得焦点时,系统会通知你的
activity
并且请求根节点去测距并绘制树 ,根节点就会请求它的子节点去绘制它们自己。每个树上的viewgroup节点都为它的子节点的绘制负责。
正如之前提到的,每个view group都有测量它的有效空间,布局它的子对象,并且调用每个子对象的Draw()方法去绘制它们自己。子对象可能会请求获得一个它们在父对象中的大小和位置,但是父对象对于每个子对象的大小和位置有最终的决定权。
4. LayoutParams
:一个子对象如何指定它的位置和大小
每个viewgroup类都会使用一个继承于Viewgroup.LayoutParams的嵌套类。这个子类包含了包含了定义一个子对象位置和大小的属性类型,并且需适用于view group类。
要注意的是,每个LayoutParams子类都有它自己赋值的语法。每个子元素必须定义适用于它们父对象的LayoutParams,尽管父对象可能会为子元素定义不同的LayoutParams。
所有的viewgroup都包括宽和高。很多还包括边界的定义(margin和border)。你可以非常精确地描述宽和高,尽管你并不想经常这么做。更多时候你希望你的view自行调整到适应内容大小,或者适应容器大小。
2.1.2 . 通用布局对象 ( 最普遍的 view groups)
1. FrameLayout (
上下压着的那种
)
FrameLayout是最简单的一个布局对象。它被定制为你屏幕上的一个空白备用区域,之后你可以在其中填充一个单一对象 — 比如,一张你要发布的图片。所有的子元素将会固定在屏幕的左上角;你不能为FrameLayout中的一个子元素指定一个位置。后一个子元素将会直接在前一个子元素之上进行
覆盖填充,把它们部份或全部挡住(除非后一个子元素是透明的)。
2. LinearLayout
LinearLayout以你为它设
置的垂直或水平的属性值,来排列所有的子元素。所有的子元素都被堆放在其它元素之后,因此一个垂直列表的每一行只会有一个元素,而不管他们有多宽,而一个水平列表将会只有一个行高(高度为最高子元素的高度加上边框高度)。 LinearLayout保持子元素之间的间隔以及互相对齐(相对一个元素的右对齐、中间对齐或者左对齐)。
LinearLayout还支持为单独的子元素指定weight。好处就是允许子元素可以填充屏幕上的剩余空间。这也避免了在一个大屏幕中,一串小对象挤成一堆的情况,而是允许他们放大填充空白。子元素指定一个weight值,剩余的空间就会按这些子元素指定的weight比例分配给这些子元素。默认的weight值为0。例如,如果有三个文本框,其中两个指定了weight值为1,那么,这两个文本框将等比例地放大,并填满剩余的空间,而第三个文本框不会放大。
Tip:为了在屏幕上创建一个按比例安排大小的layout,需要根据这个屏幕上每个元素将按什么比例显示,创建一个指定fill_parent,子元素的height或width为0,且为每一个子元素分配weight值的容器对象。
下面的两个窗体采用LinearLayout,包含一组的元素:一个按钮,几个标签,几个文本框。两个窗体都为布局做了一番修饰。文本框的width被设置为FILL_PARENT;其它元素的width被设置为WRAP_CONTENT。默认的对齐方式为左对齐。左边的窗体没有设置weight(默认为0);右边的窗体的comments文本框weight被设置为1。如果Name文本框也被设置为1,那么Name和Comments这两个文本框将会有同样的高度。
在一个水平排列的LinearLayout中,各项按他们的文本基线进行排列(第一列第一行的元素,即最上或最左,被设定为参考基线)。因此,人们在一个窗体中检索元素时,就不需要七上八下地读元素的文本了。我们可以在layout的XML中设置android:baselineAligned="false",来关闭这个设置。
3. TableLayout
TableLayout
将子元素的位置分配到行或列中。 一个TableLayout由许多的TableRow组成,每个TableRow都会定义一个row(事实上,你可以定义其它的子对象,这在下面会解释到)。TableLayout容器不会显示row、cloumns或cell的边框线。每个row拥有0个或多个的cell;每个cell拥有一个View对象。表格由列和行组成许多的单元格。表格允许单元格为空。单元格不能跨列,这与HTML中的不一样。下图显示了一个TableLayout,图中的虚线代表不可视的单元格边框。
列可以被隐藏,也可以被设置为伸展的从而填充可利用的屏幕空间,也可以被设置为强制列收缩直到表格匹配屏幕大小。对于更详细信息,可以查看这个类的参考文档。
4. AbsoluteLayout
AbsoluteLayout可以让子元素指定准确的x/y坐标值,并显示在屏幕上。(0, 0)为左上角,当向下或向右移动时,坐标值将变大。AbsoluteLayout没有页边框,允许元素之间互相重叠(尽管不推荐)。
我们通常不推荐使用
AbsoluteLayout
,除非你有正当理由要使用它,因为它使界面代码太过刚性,以至于在不同的设备上可能不能很好地工作 。
5. RelativeLayout
RelativeLayout允许子元素指定他们相对于其它元素或父元素的位置(通过ID指定)。因此,你可以以右对齐,或上下,或置于屏幕中央的形式来排列两个元素。元素按顺序排列,因此如果第一个元素在屏幕的中央,那么相对于这个元素的其它元素将以屏幕中央的相对位置来排列。如果使用XML来指定这个layout,在你定义它之前,被关联的元素必须定义。
这是一个RelativeLayout例子,其中有可视的和不可视的元素。基础的屏幕layout对象是一个RelativeLayout对象。
这个视图显示了屏幕元素的类名称,下面是每个元素的属性列表。这些属性一部份是由元素直接提供,另一部份是由容器的LayoutParams成员(RelativeLayout的子类)提供。RelativeLayout参数有width,height,below,alignTop,toLeft,padding和marginLeft。注意,这些参数中的一部份,其值是相对于其它子元素而言的,所以才RelativeLayout。这些参数包括toLeft,alignTop和below,用来指定相对于其它元素的左,上和下的位
以上是关于Android学习笔记 ( by quqi99 )的主要内容,如果未能解决你的问题,请参考以下文章