basic4android 开发教程翻译(五)Android进程及activitys 生存周期

xalion

Member
Licensed User
Longtime User
简而言之 :
每个 Basic4android 程序在它自己的进程中运行.
一个进程拥有一个主线程,这个主线程也叫做UI 线程,它会一直运行到进程结束.一个进程也可以有好几个线程,这些线程用来做一些后台工作.

当用户启动一个应用时,一个进程就开始了工作, 假设其并没有已经在后台运行.

进程的结束是不确定的. 有时可能发生在用户或者系统关闭掉所有的activities后.
假设你有一个activity,当用户按了返回键,这个activity被关闭了. 以后当电话的内存不够时这个进程就会退出了(最后肯定会出现这种情况的).
如果用户再次运行这个程序时,而这个进程并没有被杀掉的话,这个进程就会被再次使用.

一个Basic4android应用是由一个或者多个activities组成. Android 支持其他几个"main"元件.这些以后将在以后版本的Basic4android中加入.

Activities有点类似wondows 的窗体.
主要的差别是当一个activity不在前台时,为了节省内存, 这个activity可能会被杀掉. 通常在activity消失前,你需要保存它的状态. 要么保存到一个持久的存储上,要么保存到它的进程的内存里.
以便以后当需要这个activity时,重新建立它.

另一个需要小心的地方是当设备的主要配置发生变化时. 最常见情况是方向的变化(用户旋转了设备). 当这些变化发生时,当前的activities会被销毁和重建. 现在当我们建立activity时,我们可以根据新的配置来建立 (例如, 我们现在知道新的屏幕尺寸).
我们如何处理这些呢?
当你建立一个新的activity时,你可以使用下面的代码模版:
Code:
Sub Process_Globals
'These global variables will be declared once when the application starts.
'These variables can be accessed from all modules.

End Sub

Sub Globals
'These global variables will be redeclared each time the activity is created.
'These variables can only be accessed from this module.

End Sub

Sub Activity_Create(FirstTime As Boolean)

End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub
变量可以是全局的和局部的. 局部变量是定义在子程里面而不是定义在Process_Globals 和Globals里.
局部变量被限制在本子程内. 子程一旦结束,这些变量就不再存在.
全局变量可以被所有的子程访问.

有两种类型的全局变量.
进程变量和activity变量.

进程变量 - 这些变量与进程的生存期一致.
你应该把把这些变量定义到sub Process_Globals里面.
当进程开始时,这个子程被调用一次(不仅仅是第一个activitie,对所有的activities都一样).
这些变量应该仅仅是"公开"变量. 这意味着它们也可以被其它模块访问.
然而,不是所有类型的对象都可以被定义为进程变量.
例如,所有的views不能被定义成进程变量.
主要原因是我们不想保留一个可能随着activity销毁而被销毁的引用对象.
换句话说,一旦activity被销毁了, activity上所有的views 也会同时被销毁.
如果我们保留着一个view的引用,垃圾收集器就不能释放这些资源,就会造成内存泄漏.
编译器强制执行这个要求.

Activity变量 - 这些变量包含在activity中.
你应该在Sub Globals中定义这些变量.
这些变量是 "私有的"并且只能在当前activity模块中访问.
所有的对象类型都可以被定义为activity变量.
每次activity建立时, Sub Globals就会被调用(在Activity_Create之前).
这些变量的生存期与这个activity一致.

Sub Activity_Create (FirstTime As Boolean)
当activity建立后,就会调用这个子程.
当用户启动应用时,activity就会被建立, 当设备的配置发生变化时(用户转动设备),这个activity就会被销毁.另外,当这个activity在后台时,为了释放内存,OS 也可能会决定销毁它.
这个子程应该用来载入或者建立layout (当然也可以做其他用处).
FirstTime 参数用来告诉我们是不是第一次建立这个activity. Firsttime相对于当前进程.
你可以使用FirstTime来完成有关进程变量的各种初始化工作.
例如,如果你需要读一个含有一个列表的文件,当FirstTime是True 的时候,你可以读取这个文件并将文件中的列表保存为进程变量.
现在我们就可以知道这个列表在整个进程的生存期会存在,而不需要每次activity建立后都重新读取这个列表.

总而言之, 你可以检查FirstTime是否为True,然后初始化进程变量.

Sub Activity_Resume 和 Sub Activity_Pause (UserClosed As Boolean)
每次当activity从前台转换到后台时就会调用 Activity_Pause子程.
当activity 在前台时,但是配置发生变化时 (这会导致activity暂停并被销毁), 也会调用Activity_Pause子程.
Activity_Pause 是保存重要信息的最后的一个地方.
一般有两种机制来让你保存activity状态.
仅与当前应用有关的信息可以被保存到一个或多个进程变量中.
其他信息应该保存到持久存储上(文件或者是数据库).
例如,如果用户改变了一些设置,你应该在这里把这些改变保存到持久存储上. 否则这些变化可能会丢失.

当Activity_Create完成后会立刻调用Activity_Resume.另外就是当继续一个暂停的activity也会调用它 (被切换到后台的activity又被切换到前台).
注意:当你打开一个不同的activity时 (通过调用 StartActivity),当前的进程首先被暂停,然后另外的activity将被建立(如果需要的话),然后当前进程会继续执行(总是这样).

通过以上讨论, 每次当activity从前台切换到后台时Activity_Pause就会被调用. 这可能是以下原因造成的:
1. 启动了一个不同的activity.
2. Home键被按了.
3. 配置改变事件被触发(例如方向发生变化).
4. Backj键被按了.

在1和2的情况下, activity将会被暂停,并被保存到内存中以便以后再次使用.
在3的情况下, activity将会被暂停,销毁.然后再建立(并继续).
在4的情况下, activity将会被暂停然后销毁. 按Back键类似与关闭activity. 在这种情况下,你没必要保存任何实例特定的信息(例如PacMan游戏中的pacman的位置).
这中情况下,UserClosed 参数为true.其他情况下都是false. 请注意当你调用Activity.Finish时,它也是true. 这个方法暂停和销毁当前activity,和Back键类似.

你可以使用UserClosed 参数来决定需要保存那些数据和重置任何相关的进程变量为初始化值(如果位置是进程变量的话,移动pacman的位置到中间).

处理UI状态的一个新模块请参考这里: http://www.b4x.com/forum/basic...ngs-state.html
 
Top