【Android源码 栏目提醒】:以下是网学会员为您推荐的Android源码 -Android应用程序的Activity启动过程简要介绍和学习计划 - 企业软件开发,希望本篇文章对您学习有所帮助。
Android应用程序的Activity启动过程简要介绍和学习计划 在
Android系统中Activity和Service是应用程序的核心组件它们以松藕合的方式组合在一起构成了一个完整的应用程序这得益于应用程序框架层提供了一套完整的机制来协助应用程序启动这些Activity和Service以及提供Binder机制帮助它们相互间进行通信。
在前面的文章
Android进程间通信IPC机制Binder简要介绍和学习计划和
Android系统在新进程中启动自定义服务过程startService的原理分析中我们已经系统地介绍了Binder机制和Service的启动过程了在本文中简要介绍Activity的启动过程以及后续学习计划。
在
Android系统中有两种操作会引发Activity的启动一种用户点击应用程序图标时Launcher会为我们启动应用程序的主Activity应用程序的默认Activity启动起来后它又可以在内部通过调用startActvity接口启动新的Activity依此类推每一个Activity都可以在内部启动新的Activity。
通过这种连锁反应按需启动Activity从而完成应用程序的功能。
这里我们通过一个具体的例子来说明如何启动
Android应用程序的Activity。
Activity的启动方式有两种一种是显式的一种是隐式的隐式启动可以使得Activity之间的藕合性更加松散因此这里只关注隐式启动Activity的方法。
首先在
Android源代码工程的packages/experimental目录下创建一个应用程序工程目录Activity。
关于如何获得
Android源代码工程请参考在Ubuntu上下载、编译和安装
Android最新源代码一文关于如何在
Android源代码工程中创建应用程序工程请参考在Ubuntu上为
Android系统内置Java应用程序测试Application Frameworks层的硬件服务一文。
这里工程名称就是Activity了它定义了一个路径为shy.luo.activity的package这个例子的源代码主要就是实现在这里了。
下面将会逐一介绍这个package里面的文件。
应用程序的默认Activity定义在src/shy/luo/activity/MainActivity.java文件中 view plaincopy to clipboardprint 1. package shy.luo.activity 2. 3. import shy.luo.activity.R 4. 5. import
android.app.Activity 6. import
android.content.Intent 7. import
android.os.Bundle 8. import
android.util.Log 9. import
android.view.View 10. import
android.view.View.OnClickListener 11. import
android.widget.Button 12. 13. public class MainActivity extends Activity implements OnClickListener 14. private final static String LOG_TAG shy.luo.activity.MainActivity 15. 16. private Button startButton null 17. 18. Override 19. public void onCreateBundle savedInstanceState 20. super.onCreatesavedInstanceState 21. setContentViewR.layout.main 22. 23. startButton ButtonfindViewByIdR.id.button_start 24. startButton.setOnClickListenerthis 25. 26. Log.iLOG_TAG Main Activity Created. 27. 28. 29. Override 30. public void onClickView v 31. ifv.equalsstartButton 32. Intent intent new Intentshy.luo.activity.subactivity 33. startActivityintent 34. 35. 36. 它的实现很简单当点击它上面的一个按钮的时候就会启动另外一个名字为“shy.luo.activity.subactivity”的Actvity。
名字为“shy.luo.activity.subactivity”的Actvity实现在src/shy/luo/activity/SubActivity.java文件中 view plaincopy to clipboardprint 1. package shy.luo.activity 2. 3. import
android.app.Activity 4. import
android.os.Bundle 5. import
android.util.Log 6. import
android.view.View 7. import
android.view.View.OnClickListener 8. import
android.widget.Button 9. 10. public class SubActivity extends Activity implements OnClickListener 11. private final static String LOG_TAG shy.luo.activity.SubActivity 12. 13. private Button finishButton null 14. 15. Override 16. public void onCreateBundle savedInstanceState 17. super.onCreatesavedInstanceState 18. setContentViewR.layout.sub 19. 20. finishButton ButtonfindViewByIdR.id.button_finish 21. finishButton.setOnClickListenerthis 22. 23. Log.iLOG_TAG Sub Activity Created. 24. 25. 26. Override 27. public void onClickView v 28. ifv.equalsfinishButton 29. finish 30. 31. 32. 它的实现也很简单当点击上面的一个铵钮的时候就结束自己回到前面一个Activity中去。
这里我们可以看到
Android应用程序架构中非常核心的一点MainActivity不需要知道SubActivity的存在即它不直接拥有SubActivity的接口但是它可以通过一个字符串来告诉应用程序框架层它要启动的Activity的名称是什么其它的事情就交给应用程序框架层来做当然应用程序框架层会根据这个字符串来找到其对应的Activity然后把它启动起来。
这样就使得
Android应用程序中的Activity藕合性很松散从而使得
Android应用程序的模块性程度很高并且有利于以后程序的维护和更新对于大型的客户端软件来说这一点是非常重要的。
当然应用程序框架能够根据名字来找到相应的Activity是需要应用程序本身来配合的这就是要通过应用程序的配置文件AndroidManifest.xml来实现了 view plaincopy to clipboardprint 1. 2. 6. 7. 9. 10. 11. 12. 13. 14. 16. 17. 18. 19. 20. 21. 22. 从这个配置文件中我们可以看到MainActivity被配置成了应用程序的默认Activity即用户在手机屏幕上点击Activity应用程序图标时Launcher就会默认启动MainActivity这个Activity view plaincopy to clipboardprint 1. 3. 4. 5. 6. 7. 这个配置文件也将名字“shy.luo.activity.subactivity”和SubActivity关联了起来因此应用程序框架层能够根据名字来找到它 view plaincopy to clipboardprint 1. 3. 4. 5. 6. 7. 下面再列出这个应用程序的界面配置文件和字符串文件。
界面配置文件在res/layout目录中main.xml文件对应MainActivity的界面 view plaincopy to clipboardprint 1. 2. 7. 13. 14. 而sub.xml对应SubActivity的界面 view plaincopy to clipboardprint 1. 2. 7. 13. 14. 字符串文件位于res/values/strings.xml文件中 view plaincopy to clipboardprint 1. 2. 3. Activity 4. Sub Activity 5. Start sub-activity 6. Finish activity 7. 最后我们还要在工程目录下放置一个编译脚本文件
Android.mk view plaincopy to clipboardprint 1. LOCAL_PATH: call my-dir 2. include CLEAR_VARS 3. 4. LOCAL_MODULE_TAGS : optional 5. 6. LOCAL_SRC_FILES : call all-subdir-java-files 7. 8. LOCAL_PACKAGE_NAME : Activity 9. 10. include BUILD_PACKAGE 这样整个例子的源代码实现就介绍完了接下来就要编译了。
有关如何单独编译
Android源代码工程的模块以及如何打包system.img请参考如何单独编译
Android源代码中的模块一文。
执行以下命令进行编译和打包 view plaincopy to clipboardprint 1. USER-NAMEMACHINE-NAME:/
Android mmm packages/experimental/Activity 2. USER-NAMEMACHINE-NAME:/
Android make snod 这样打包好的
Android系统镜像文件system.img就包含我们前面创建的Activity应用程序了。
再接下来就是运行模拟器来运行我们的例子了。
关于如何在
Android源代码工程中运行模拟器请参考在Ubuntu上下载、编译和安装
Android最新源代码一文。
执行以下命令启动模拟器 view plaincopy to clipboardprint 1. USER-NAMEMACHINE-NAME:/
Android emulator 模拟器启动起就可以在屏幕上看到Activity应用程序图标了 点击Activity这个应用程序图标后Launcher就会把MainActivity启动起来 点击上面的Start sub-activity铵钮MainActivity内部就会通过startActivity接口来启动SubActivity view plaincopy to clipboardprint 1. Intent intent new Intentshy.luo.activity.subactivity 2. startActivityintent 如下图所示 无论是通过点击应用程序图标来启动Activity还是通过Activity内部调用startActivity接口来启动新的Activity都要借助于应用程序框架层的ActivityManagerService服务进程。
在前面一篇文章
Android系统在新进程中启动自定义服务过程startService的原理分析中我们已经看到Service也是由ActivityManagerService进程来启动的。
在
Android应用程序框架层中ActivityManagerService是一个非常重要的接口它不但负责启动Activity和Service还负责管理Activity和Service。
Android应用程序框架层中的ActivityManagerService启动Activity的过程大致如下图所示 在这个图中ActivityManagerService和ActivityStack位于同一个进程中而ApplicationThread和ActivityThread位于另一个进程中。
其中ActivityManagerService是负责管理Activity的生命周期的ActivityManagerService还借助ActivityStack是来把所有的Activity按照后进先出的顺序放在一个堆栈中对于每一个应用程序来说都有一个ActivityThread来表示应用程序的主进程而每一个ActivityThread都包含有一个ApplicationThread实例它是一个Binder对象负责和其它进程进行通信。
下面简要介绍一下启动的过程 Step 1. 无论是通过Launcher来启动Activity还是通过Activity内部调用startActivity接口来启动新的Activity都通过Binder进程间通信进入到ActivityManagerService进程中并且调用ActivityManagerService.startActivity接口 Step 2. ActivityManagerService调用ActivityStack.startActivityMayWait来做准备要启动的Activity的相关信息 Step 3. ActivityStack通知ApplicationThread要进行Activity启动调度了这里的ApplicationThread代表的是调用ActivityManagerService.startActivity接口的进程对于通过点击应用程序图标的情景来说这个进程就是Launcher了而对于通过在Activity内部调用startActivity的情景来说这个进程就是这个Activity所在的进程了 Step 4. ApplicationThread不执行真正的启动操作它通过调用ActivityManagerService.activityPaused接口进入到ActivityManagerService进程中看看是否需要创建新的进程来启动Activity Step 5. 对于通过点击应用程序图标来启动Activity的情景来说ActivityManagerService在这一步中会调用startProcessLocked来创建一个新的进程而对于通过在Activity内部调用startActivity来启动新的Activity来说这一步是不需要执行的因为新的Activity就在原来的Activity所在的进程中进行启动 Step 6. ActivityManagerServic调用ApplicationThread.scheduleLaunchActivity接口通知相应的进程执行启动Activity的操作 Step 7. ApplicationThread把这个启动Activity的操作转发给ActivityThreadActivityThread通过ClassLoader导入相应的Activity类然后把它启动起来。
这样
Android应用程序的Activity启动过程就简要介绍到这里了在接下来的两篇文章中我们将根据Activity的这两种启动情景深入到应用程序框架层的源代码里面去一步一步地分析它们的启动过程 1.
Android应用程序启动过程的源代码分析 2.
Android应用程序内部启动Activity过程startActivity的源代码分析。
上一篇:
Beginning Android 2简体中文版第二章
下一篇:
7*30m公路预应力混凝土连续梁桥上部结构设计