文档视界 最新最全的文档下载
当前位置:文档视界 › Android程序启动过程源码分析

Android程序启动过程源码分析

Android程序启动过程源码分析
Android程序启动过程源码分析

Android应用程序启动过程源代码分析

分类:Android 2011-08-19 00:58 5447人阅读评论(40) 收藏举报

前文简要介绍了Android应用程序的Activity的启动过程。在Android系统中,应用程序是由Activity组成的,因此,应用程序的启动过程实际上就是应用程序中的默认Activity 的启动过程,本文将详细分析应用程序框架层的源代码,了解Android应用程序的启动过程。

在上一篇文章Android应用程序的Activity启动过程简要介绍和学习计划中,我们举例子说明了启动Android应用程序中的Activity的两种情景,其中,在手机屏幕中点击应用程序图标的情景就会引发Android应用程序中的默认Activity的启动,从而把应用程序启动起来。这种启动方式的特点是会启动一个新的进程来加载相应的Activity。这里,我们继续以这个例子为例来说明Android应用程序的启动过程,即MainActivity的启动过程。

MainActivity的启动过程如下图所示:

点击查看大图下面详细分析每一步是如何实现的。

Step 1. Launcher.startActivitySafely

在Android系统中,应用程序是由Launcher启动起来的,其实,Launcher本身也是一个应用程序,其它的应用程序安装后,就会Launcher的界面上出现一个相应的图标,点击这个图标时,Launcher就会对应的应用程序启动起来。

Launcher的源代码工程在packages/apps/Launcher2目录下,负责启动其它应用程序的源代码实现在src/com/android/launcher2/Launcher.java文件中:

view plaincopy to clipboardprint?

1./**

2.* Default launcher application.

3.*/

4.public final class Launcher extends Activity

5. implements View.OnClickListener, OnLongClickListener, LauncherMod

el.Callbacks, AllAppsView.Watcher {

6.

7. ......

8.

9. /**

10. * Launches the intent referred by the clicked shortcut.

11. *

12. * @param v The view representing the clicked shortcut.

13. */

14. public void onClick(View v) {

15. Object tag = v.getTag();

16. if (tag instanceof ShortcutInfo) {

17. // Open shortcut

18. final Intent intent = ((ShortcutInfo) tag).intent;

19. int[] pos = new int[2];

20. v.getLocationOnScreen(pos);

21. intent.setSourceBounds(new Rect(pos[0], pos[1],

22. pos[0] + v.getWidth(), pos[1] + v.getHeight()));

23. startActivitySafely(intent, tag);

24. } else if (tag instanceof FolderInfo) {

25. ......

26. } else if (v == mHandleView) {

27. ......

28. }

29. }

30.

31. void startActivitySafely(Intent intent, Object tag) {

32. intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

33. try {

34. startActivity(intent);

35. } catch (ActivityNotFoundException e) {

36. ......

37. } catch (SecurityException e) {

38. ......

39. }

40. }

41.

42. ......

43.

44.}

1.

2.android:label="@string/app_name">

3.

4.

5.

6.

7.

1.public class Activity extends ContextThemeWrapper

2. implements LayoutInflater.Factory,

3. Window.Callback, KeyEvent.Callback,

4. OnCreateContextMenuListener, ComponentCallbacks {

5.

6. ......

7.

8.@Override

9. public void startActivity(Intent intent) {

10. startActivityForResult(intent, -1);

11. }

12.

13. ......

14.

15.}

1.public class Activity extends ContextThemeWrapper

2. implements LayoutInflater.Factory,

3. Window.Callback, KeyEvent.Callback,

4. OnCreateContextMenuListener, ComponentCallbacks {

5.

6. ......

7.

8. public void startActivityForResult(Intent intent, int requestCode) {

9. if (mParent == null) {

10. Instrumentation.ActivityResult ar =

11. mInstrumentation.execStartActivity(

12. this, mMainThread.getApplicationThread(), mToken, this,

13. intent, requestCode);

14. ......

15. } else {

16. ......

17. }

18.

19.

20. ......

21.

22.}

1.public class Instrumentation {

2.

3. ......

4.

5. public ActivityResult execStartActivity(

6. Context who, IBinder contextThread, IBinder token, Activity target,

7. Intent intent, int requestCode) {

8. IApplicationThread whoThread = (IApplicationThread) contextThread

;

9. if (mActivityMonitors != null) {

10. ......

11. }

12. try {

13. int result = ActivityManagerNative.getDefault()

14. .startActivity(whoThread, intent,

15. intent.resolveTypeIfNeeded(who.getContentResolver()),

16. null, 0, token, target != null ? target.mEmbeddedID : nul

l,

17. requestCode, false, false);

18. ......

19. } catch (RemoteException e) {

20. }

21. return null;

22. }

23.

24. ......

25.

26.}

1.class ActivityManagerProxy implements IActivityManager

2.{

3.

4. ......

5.

6. public int startActivity(IApplicationThread caller, Intent intent,

7. String resolvedType, Uri[] grantedUriPermissions, int granted

Mode,

8. IBinder resultTo, String resultWho,

9. int requestCode, boolean onlyIfNeeded,

10. boolean debug) throws RemoteException {

11. Parcel data = Parcel.obtain();

12. Parcel reply = Parcel.obtain();

13. data.writeInterfaceToken(IActivityManager.descriptor);

14. data.writeStrongBinder(caller != null ? caller.asBinder() : null)

;

15. intent.writeToParcel(data, 0);

16. data.writeString(resolvedType);

17. data.writeTypedArray(grantedUriPermissions, 0);

18. data.writeInt(grantedMode);

19. data.writeStrongBinder(resultTo);

20. data.writeString(resultWho);

21. data.writeInt(requestCode);

22. data.writeInt(onlyIfNeeded ? 1 : 0);

23. data.writeInt(debug ? 1 : 0);

24. mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);

25. reply.readException();

26. int result = reply.readInt();

27. reply.recycle();

28. data.recycle();

29. return result;

30. }

31.

32. ......

33.

34.}

1.public final class ActivityManagerService extends ActivityManagerNative

2. implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {

3.

4. ......

5.

6. public final int startActivity(IApplicationThread caller,

7. Intent intent, String resolvedType, Uri[] grantedUriPermissio

ns,

8. int grantedMode, IBinder resultTo,

9. String resultWho, int requestCode, boolean onlyIfNeeded,

10. boolean debug) {

11. return mMainStack.startActivityMayWait(caller, intent, resolvedTy

pe,

12. grantedUriPermissions, grantedMode, resultTo, resultWho,

13. requestCode, onlyIfNeeded, debug, null, null);

14. }

15.

16.

17. ......

18.

19.}

1.public class ActivityStack {

2.

3. ......

4.

5. final int startActivityMayWait(IApplicationThread caller,

6. Intent intent, String resolvedType, Uri[] grantedUriPermissio

ns,

7. int grantedMode, IBinder resultTo,

8. String resultWho, int requestCode, boolean onlyIfNeeded,

9. boolean debug, WaitResult outResult, Configuration config) {

10.

11. ......

12.

13. boolean componentSpecified = intent.getComponent() != null;

14.

15. // Don't modify the client's object!

16. intent = new Intent(intent);

17.

18. // Collect information about the target of the Intent.

19. ActivityInfo aInfo;

20. try {

21. ResolveInfo rInfo =

22. AppGlobals.getPackageManager().resolveIntent(

23. intent, resolvedType,

24. PackageManager.MATCH_DEFAULT_ONLY

25. | ActivityManagerService.STOCK_PM_FLAGS);

26. aInfo = rInfo != null ? rInfo.activityInfo : null;

27. } catch (RemoteException e) {

28. ......

29. }

30.

31. if (aInfo != null) {

32. // Store the found target back into the intent, because now t

hat

33. // we have it we never want to do this again. For example, i

f the

34. // user navigates back to this point in the history, we shoul

d

35. // always restart the exact same activity.

36. intent.setComponent(new ComponentName(

37. aInfo.applicationInfo.packageName, https://www.docsj.com/doc/a56336302.html,));

38. ......

39. }

40.

41. synchronized (mService) {

42. int callingPid;

43. int callingUid;

44. if (caller == null) {

45. ......

46. } else {

47. callingPid = callingUid = -1;

48. }

49.

50. mConfigWillChange = config != null

51. && mService.mConfiguration.diff(config) != 0;

52.

53. ......

54.

55. if (mMainStack && aInfo != null &&

56. (aInfo.applicationInfo.flags&ApplicationInfo.FLAG_CANT_SA

VE_STATE) != 0) {

57.

58. ......

59.

60. }

61.

62. int res = startActivityLocked(caller, intent, resolvedType,

63. grantedUriPermissions, grantedMode, aInfo,

64. resultTo, resultWho, requestCode, callingPid, callingUid,

65. onlyIfNeeded, componentSpecified);

66.

67. if (mConfigWillChange && mMainStack) {

68. ......

69. }

70.

71. ......

72.

73. if (outResult != null) {

74. ......

75. }

76.

77. return res;

78. }

79.

80. }

81.

82. ......

83.

84.}

1. ActivityInfo aInfo;

2. try {

3.ResolveInfo rInfo =

4.AppGlobals.getPackageManager().resolveIntent(

5. intent, resolvedType,

6. PackageManager.MATCH_DEFAULT_ONLY

7. | ActivityManagerService.STOCK_PM_FLAGS);

8.aInfo = rInfo != null ? rInfo.activityInfo : null;

9. } catch (RemoteException e) {

10. ......

11. }

接下去就调用startActivityLocked进一步处理了。

Step 8. ActivityStack.startActivityLocked

这个函数定义在

frameworks/base/services/java/com/android/server/am/ActivityStack.java文件中:view plaincopy to clipboardprint?

1.public class ActivityStack {

2.

3. ......

4.

5. final int startActivityLocked(IApplicationThread caller,

6. Intent intent, String resolvedType,

7. Uri[] grantedUriPermissions,

8. int grantedMode, ActivityInfo aInfo, IBinder resultTo,

9. String resultWho, int requestCode,

10. int callingPid, int callingUid, boolean onlyIfNeeded,

11. boolean componentSpecified) {

12. int err = START_SUCCESS;

13.

14. ProcessRecord callerApp = null;

15. if (caller != null) {

16. callerApp = mService.getRecordForAppLocked(caller);

17. if (callerApp != null) {

18. callingPid = callerApp.pid;

19. callingUid = https://www.docsj.com/doc/a56336302.html,.uid;

20. } else {

21. ......

22. }

23. }

24.

25. ......

26.

27. ActivityRecord sourceRecord = null;

28. ActivityRecord resultRecord = null;

29. if (resultTo != null) {

30. int index = indexOfTokenLocked(resultTo);

31.

32. ......

33.

34. if (index >= 0) {

35. sourceRecord = (ActivityRecord)mHistory.get(index);

36. if (requestCode >= 0 && !sourceRecord.finishing) {

37. ......

38. }

39. }

40. }

41.

42. int launchFlags = intent.getFlags();

43.

44. if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0

45. && sourceRecord != null) {

46. ......

47. }

48.

49. if (err == START_SUCCESS && intent.getComponent() == null) {

50. ......

51. }

52.

53. if (err == START_SUCCESS && aInfo == null) {

54. ......

55. }

56.

57. if (err != START_SUCCESS) {

58. ......

59. }

60.

61. ......

62.

63. ActivityRecord r = new ActivityRecord(mService, this, callerApp,

callingUid,

64. intent, resolvedType, aInfo, mService.mConfiguration,

65. resultRecord, resultWho, requestCode, componentSpecified);

66.

67. ......

68.

69. return startActivityUncheckedLocked(r, sourceRecord,

70. grantedUriPermissions, grantedMode, onlyIfNeeded, true);

71. }

72.

73.

74. ......

75.

76.}

1.ActivityRecord r = new ActivityRecord(mService, this, callerApp, callingU

id,

2. intent, resolvedType, aInfo, mService.mConfiguration,

3. resultRecord, resultWho, requestCode, componentSpecified);

1.public class ActivityStack {

2.

3. ......

4.

5. final int startActivityUncheckedLocked(ActivityRecord r,

6. ActivityRecord sourceRecord, Uri[] grantedUriPermissions,

7. int grantedMode, boolean onlyIfNeeded, boolean doResume) {

8. final Intent intent = r.intent;

9. final int callingUid = https://www.docsj.com/doc/a56336302.html,unchedFromUid;

10.

11. int launchFlags = intent.getFlags();

12.

13. // We'll invoke onUserLeaving before onPause only if the launchin

g

14. // activity did not explicitly state that this is an automated la

unch.

15. mUserLeaving = (launchFlags&Intent.FLAG_ACTIVITY_NO_USER_ACTION)

== 0;

16.

17. ......

18.

19. ActivityRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOU

S_IS_TOP)

20. != 0 ? r : null;

21.

22. // If the onlyIfNeeded flag is set, then we can do this if the ac

tivity

23. // being launched is the same as the one making the call... or,

as

24. // a special case, if we do not know the caller then we count the

25. // current top activity as the caller.

26. if (onlyIfNeeded) {

27. ......

28. }

29.

30. if (sourceRecord == null) {

31. ......

32. } else if (https://www.docsj.com/doc/a56336302.html,unchMode == https://www.docsj.com/doc/a56336302.html,UNCH_SINGLE_

INSTANCE) {

33. ......

34. } else if (https://www.docsj.com/doc/a56336302.html,unchMode == https://www.docsj.com/doc/a56336302.html,UNCH_SINGLE_INSTANCE

35. || https://www.docsj.com/doc/a56336302.html,unchMode == https://www.docsj.com/doc/a56336302.html,UNCH_SINGLE_TASK) {

36. ......

37. }

38.

39. if (r.resultTo != null && (launchFlags&Intent.FLAG_ACTIVITY_NEW_T

ASK) != 0) {

40. ......

41. }

42.

43. boolean addingToTask = false;

44. if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&

45. (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)

46. || https://www.docsj.com/doc/a56336302.html,unchMode == https://www.docsj.com/doc/a56336302.html,UNCH_SINGLE_TASK

47. || https://www.docsj.com/doc/a56336302.html,unchMode == https://www.docsj.com/doc/a56336302.html,UNCH_SINGLE_INSTANCE) {

48. // If bring to front is requested, and no result is reque

sted, and

49. // we can find a task that was started with this same

50. // component, then instead of launching bring that one to

the front.

51. if (r.resultTo == null) {

52. // See if there is a task to bring to the front. If

this is

53. // a SINGLE_INSTANCE activity, there can be one and o

nly one

54. // instance of it in the history, and it is always in

its own

55. // unique task, so we do a special search.

56. ActivityRecord taskTop = https://www.docsj.com/doc/a56336302.html,unchMode != ActivityInfo

.LAUNCH_SINGLE_INSTANCE

57. ? findTaskLocked(intent, https://www.docsj.com/doc/a56336302.html,)

58. : findActivityLocked(intent, https://www.docsj.com/doc/a56336302.html,);

59. if (taskTop != null) {

60. ......

61. }

62. }

63. }

64.

65. ......

66.

67. if (r.packageName != null) {

68. // If the activity being launched is the same as the one curr

ently

69. // at the top, then we need to check if it should only be lau

nched

70. // once.

71. ActivityRecord top = topRunningNonDelayedActivityLocked(notTo

p);

72. if (top != null && r.resultTo == null) {

73. if (top.realActivity.equals(r.realActivity)) {

74. ......

75. }

android系统开机启动流程分析

一,系统引导bootloader 加电,cpu执行bootloader程序,正常启动系统,加载boot.img【其中包含内核。还有ramdisk】 二,内核kernel bootloader加载kernel,kernel自解压,初始化,载入built-in驱动程序,完成启动。 内核启动后会创建若干内核线程,在后装入并执行程序/sbin/init/,载入init process,切换至用户空间(user-space) 内核zImage解压缩 head.S【这是ARM-Linux运行的第一个文件,这些代码是一个比较独立的代码包裹器。其作用就是解压Linux内核,并将PC指针跳到内核(vmlinux)的第一条指令】首先初始化自解压相关环境(内存等),调用decompress_kernel进行解压,解压后调用start_kernel启动内核【start_kernel是任何版本linux内核的通用初始化函数,它会初始化很多东西,输出linux版本信息,设置体系结构相关的环境,页表结构初始化,设置系 统自陷入口,初始化系统IRQ,初始化核心调度器等等】,最后调用rest_init【rest_init 会调用kernel_init启动init进程(缺省是/init)。然后执行schedule开始任务调度。这个init是由android的./system/core/init下的代码编译出来的,由此进入了android的代码】。 三,Init进程启动 【init是kernel启动的第一个进程,init启动以后,整个android系统就起来了】 init进程启动后,根据init.rc 和init. .rc脚本文件建立几个基本 服务(servicemanager zygote),然后担当property service 的功能 打开.rc文件,解析文件内容。【system/core/init/init.c】将service信息放置到service.list中【system/core/init/init_parser.c】。 建立service进程。【service_start(…) execve(…)】 在init.c中,完成以下工作 1、初始化log系统【解析/init.rc和init.%hardware%.rc文件,在两个 文件解析步骤2时执行“early-init”行动】 2、初始化设备【在/dev下创建所有设备节点,下载firmwares】 3、初始化属性服务器【在两个文件解析步骤2时执行“init”行动】

Android Hotfix 新方案——Amigo 源码解读

Android Hotfix 新方案——Amigo 源码解读 首先我们先来看看如何使用这个库。 用法 在project 的build.gradle中 dependencies { classpath 'me.ele:amigo:0.0.3' } 在module 的build.gradle中 apply plugin: 'me.ele.amigo' 就这样轻松的集成了Amigo。 生效补丁包 补丁包生效有两种方式可以选择: ? 稍后生效补丁包 ? 如果不想立即生效而是用户第二次打开App 时才打入补丁包,则可以将新的Apk 放到/data/data/{your pkg}/files/amigo/demo.apk,第二次打开时就会自动生效。可以通过这个方法 ? File hotfixApk = Amigo.getHotfixApk(context); ?

获取到新的Apk。 同时,你也可以使用Amigo 提供的工具类将你的补丁包拷贝到指定的目录当中。 ? FileUtils.copyFile(yourApkFile, amigoApkFile); ? ? 立即生效补丁包 ? 如果想要补丁包立即生效,调用以下两个方法之一,App 会立即重启, 并且打入补丁包。 ? Amigo.work(context); ? Amigo.work(context, apkFile); ? 删除补丁包 如果需要删除掉已经下好的补丁包,可以通过这个方法 Amigo.clear(context); 提示:如果apk 发生了变化,Amigo 会自动清除之前的apk。 自定义界面 在热修复的过程中会有一些耗时的操作,这些操作会在一个新的进程中的Activity 中执行,所以你可以通过以下方式来自定义这个Activity。

Android 开机启动流程

Android的开机流程 1. 系统引导bootloader 1) 源码:bootable/bootloader/* 2) 说明:加电后,CPU将先执行bootloader程序,此处有三种选择 a) 开机按Camera+Power启动到fastboot,即命令或SD卡烧写模式,不加载内核及文件系统,此处可以进行工厂模式的烧写 b) 开机按Home+Power启动到recovery模式,加载recovery.img,recovery.i mg包含内核,基本的文件系统,用于工程模式的烧写 c) 开机按Power,正常启动系统,加载boot.img,boot.img包含内核,基本文件系统,用于正常启动手机(以下只分析正常启动的情况) 2. 内核kernel 1) 源码:kernel/* 2) 说明:kernel由bootloader加载 3. 文件系统及应用init 1) 源码:system/core/init/* 2) 配置文件:system/rootdir/init.rc, 3) 说明:init是一个由内核启动的用户级进程,它按照init.rc中的设置执行:启动服务(这里的服务指linux底层服务,如adbd提供adb支持,vold提供SD卡挂载等),执行命令和按其中的配置语句执行相应功能 4. 重要的后台程序zygote 1)源码:frameworks/base/cmds/app_main.cpp等 2) 说明:zygote是一个在init.rc中被指定启动的服务,该服务对应的命令是/system/bin/app_process a)建立Java Runtime,建立虚拟机 b) 建立Socket接收ActivityManangerService的请求,用于Fork应用程序 c) 启动System Server 5. 系统服务system server 1)源码:frameworks/base/services/java/com/android/server/SystemServer.jav a 2) 说明:被zygote启动,通过SystemManager管理android的服务(这里的服务指frameworks/base/services下的服务,如卫星定位服务,剪切板服务等) 6. 桌面launcher 1)源码:ActivityManagerService.java为入口,packages/apps/launcher*实现 2) 说明:系统启动成功后SystemServer使用xxx.systemReady()通知各个服务,系统已经就绪,桌面程序Home就是在ActivityManagerService.systemReady()通知的过程中建立的,最终调用()启launcher 7. 解锁 1) 源码: frameworks/policies/base/phone/com/android/internal/policy/impl/*lock* 2) 说明:系统启动成功后SystemServer调用wm.systemReady()通知WindowManagerService,进而调用PhoneWindowManager,最终通过LockPatternKeyguardView显示解锁界面,跟踪代码可以看到解锁界面并不是一个Activity,这是只是向特定层上绘图,其代码了存放在特殊的位置

Android源码下载方法详解

Android: Android源码下载方法详解 分类:Android平台 安卓源码下载地址:https://www.docsj.com/doc/a56336302.html,/source/downloading.html 相信很多下载过内核的人都对这个很熟悉 git clone git://https://www.docsj.com/doc/a56336302.html,/kernel/common.git kernel 但是这是在以前,现在如果这么执行的话,会显示如下内容 Initialized empty Git repository in /home/star/working/kernel/.git/ https://www.docsj.com/doc/a56336302.html,[0: 149.20.4.77]: errno=Connection refused fatal: unable to connect a socket (Connection refused) 通过浏览器输入https://www.docsj.com/doc/a56336302.html,/,发现该网站已经被重定向为 https://www.docsj.com/doc/a56336302.html,/source/downloading.html 可以在该页面的最后发现内核的下载方法。 下面我们介绍一下Android源码下载的步骤。 工作环境: 操作系统:Ubuntu 10.04 或Ubuntu10.10 git程序:1.7.0.4 或1.7.1 转载请注明出处:https://www.docsj.com/doc/a56336302.html,/pku_android 方法一: 1.1 初始化安装环境 参考网页https://www.docsj.com/doc/a56336302.html,/source/initializing.html 主要要做的就是安装jdk和安装一些软件包 $ sudo apt-get install git-core gnupg flex bison gperf build-essential \ zip curl zlib1g-dev libc6-dev libncurses5-dev x11proto-core-dev \ libx11-dev libreadline6-dev libgl1-mesa-dev tofrodos python-markdown \ libxml2-utils 如果已经安装了,就不许要这步了 1.2 无论下载内核和源码,都需要进行如下操作 参考网页https://www.docsj.com/doc/a56336302.html,/source/downloading.html $ mkdir ~/bin $ PATH=~/bin:$PATH $ curl https://https://www.docsj.com/doc/a56336302.html,/dl/googlesource/git-repo/repo > ~/bin/repo 如果出现: repo init error: could not verify the tag 'v1.12.7',

分析Android 开机启动慢的原因

开机启动花了40多秒,正常开机只需要28秒就能开机起来。 内核的启动我没有去分析,另一个同事分析的。我主要是分析从SystemServer启来到开机动画结束显示解锁界面的这段时间,也就是开机动画的第三个动画开始到结束这段时间,这是个比较耗时阶段,一般都在17秒左右(见过牛B的手机,只需5秒)。 SystemServer分两步执行:init1和init2。init1主要是初始化native的服务,代码在sy stem_init.cpp的system_init,初始化了SurfaceFlinger和SensorService这两个native的服务。init2启动的是java的服务,比如ActivityManagerService、WindowManagerService、PackageManagerService等,在这个过程中PackageManagerService用的时间最长,因为PackageManagerService会去扫描特定目录下的jar包和apk文件。 在开机时间需要40多秒的时,从Log上可以看到,从SurfaceFlinger初始化到动画结束,要27秒左右的时间,即从SurfaceFlinger::init的LOGI("SurfaceFlinger is starting")这句Log到void SurfaceFlinger::bootFinished()的LOGI("Boot is finished (%ld ms)", long(ns 2ms(duration)) ),需要27秒左右的时间,这显然是太长了,但到底是慢在哪了呢?应该在个中间的点,二分一下,于是想到了以启动服务前后作为分隔:是服务启动慢了,还是在服务启动后的这段时间慢?以ActivityManagerService的Slog.i(TAG, "System now ready")的这句Log为分割点,对比了一下,在从SurfaceFlinger is starting到System now read y多了7秒左右的时间,这说明SystemServer在init1和init2过程中启动慢了,通过排查,发现在init1启动的时候,花了7秒多的时间,也就是system_init的LOGI("Entered system _init()")到LOGI("System server: starting Android runtime.\n")这段时间用了7秒多,而正常情况是400毫秒便可以初始化完,通过添加Log看到,在SensorService启动时,用了比较长的时间。 不断的添加Log发现,在启动SensorService时候,关闭设备文件变慢了,每次关闭一个/dev/input/下的设备文件需要100ms左右,而SensorService有60~70次的关闭文件,大概有7s左右的时间。 调用流程是: frameworks/base/cmds/system_server/library/system_init.cpp: system_init->SensorServi ce::instantiate frameworks/native/services/sensorservice/SensorService.cpp: void SensorService::onFi rstRef()->SensorDevice& dev(SensorDevice::getInstance()) hardware/libsensors/SensorDevice.cpp: SensorDevice::SensorDevice()->sensors_open hardware/libsensors/sensors.cpp: open_sensors->sensors_poll_context_t sensors_poll_context_t执行打开每个传感器设备时,遍历/dev/input/目录下的设备文件,以匹配当前需要打开的设备,遍历文件是在 hardware/libsensors/SensorBase.cpp的openInput下实现,如果打开的设备文件不是正在打开的设备文件,会执行下面语句的else部分: if (!strcmp(name, inputName)) { strcpy(input_name, filename); break;

基于MT6752的 android 系统启动流程分析报告

基于MT6752的Android系统启动流程分析报告 1、Bootloader引导 (2) 2、Linux内核启动 (23) 3、Android系统启动 (23) 报告人: 日期:2016.09.03

对于Android整个启动过程来说,基本可以划分成三个阶段:Bootloader引导、Linux kernel启动、Android启动。但根据芯片架构和平台的不同,在启动的Bootloader阶段会有所差异。 本文以MTK的MT6752平台为例,分析一下基于该平台的Android系统启动流程。 1、Bootloader引导 1.1、Bootloader基本介绍 BootLoader是在操作系统运行之前运行的一段程序,它可以将系统的软硬件环境带到一个合适状态,为运行操作系统做好准备,目的就是引导linux操作系统及Android框架(framework)。 它的主要功能包括设置处理器和内存的频率、调试信息端口、可引导的存储设备等等。在可执行环境创建好之后,接下来把software装载到内存并执行。除了装载software,一个外部工具也能和bootloader握手(handshake),可指示设备进入不同的操作模式,比如USB下载模式和META模式。就算没有外部工具的握手,通过外部任何组合或是客户自定义按键,bootloader也能够进入这些模式。 由于不同处理器芯片厂商对arm core的封装差异比较大,所以不同的arm处理器,对于上电引导都是由特定处理器芯片厂商自己开发的程序,这个上电引导程序通常比较简单,会初始化硬件,提供下载模式等,然后才会加载通常的bootloader。 下面是几个arm平台的bootloader方案: marvell(pxa935) : bootROM + OBM + BLOB informax(im9815) : bootROM + barbox + U-boot mediatek(mt6517) : bootROM + pre-loader + U-boot broadcom(bcm2157) : bootROM + boot1/boot2 + U-boot 而对MT6752平台,MTK对bootloader引导方案又进行了调整,它将bootloader分为以下两个部分: (1) 第1部分bootloader,是MTK内部(in-house)的pre-loader,这部分依赖平台。 (2) 第2部分bootloader,是LK(little kernel的缩写,作用同常见的u-boot差不多),这部分依赖操作系统,负责引导linux操作系统和Android框架。 1.2、bootloader的工作流程 1.2.1 bootloader正常的启动流程 先来看启动流程图:

Android源代码结构分析

目录 一、源代码结构 (2) 第一层次目录 (2) bionic目录 (3) bootloader目录 (5) build目录 (7) dalvik目录 (9) development目录 (9) external目录 (13) frameworks目录 (19) Hardware (20) Out (22) Kernel (22) packages目录 (22) prebuilt目录 (27) SDK (28) system目录 (28) Vendor (32)

一、源代码结构 第一层次目录 Google提供的Android包含了原始Android的目标机代码,主机编译工具、仿真环境,代码包经过解压缩后,第一级别的目录和文件如下所示: . |-- Makefile (全局的Makefile) |-- bionic (Bionic含义为仿生,这里面是一些基础的库的源代码) |-- bootloader (引导加载器),我们的是bootable, |-- build (build目录中的内容不是目标所用的代码,而是编译和配置所需要的脚本和工具) |-- dalvik (JAVA虚拟机) |-- development (程序开发所需要的模板和工具) |-- external (目标机器使用的一些库) |-- frameworks (应用程序的框架层) |-- hardware (与硬件相关的库) |-- kernel (Linux2.6的源代码) |-- packages (Android的各种应用程序) |-- prebuilt (Android在各种平台下编译的预置脚本) |-- recovery (与目标的恢复功能相关) `-- system (Android的底层的一些库)

linux内核启动 Android系统启动过程详解

linux内核启动+Android系统启动过程详解 第一部分:汇编部分 Linux启动之 linux-rk3288-tchip/kernel/arch/arm/boot/compressed/ head.S分析这段代码是linux boot后执行的第一个程序,完成的主要工作是解压内核,然后跳转到相关执行地址。这部分代码在做驱动开发时不需要改动,但分析其执行流程对是理解android的第一步 开头有一段宏定义这是gnu arm汇编的宏定义。关于GUN 的汇编和其他编译器,在指令语法上有很大差别,具体可查询相关GUN汇编语法了解 另外此段代码必须不能包括重定位部分。因为这时一开始必须要立即运行的。所谓重定位,比如当编译时某个文件用到外部符号是用动态链接库的方式,那么该文件生成的目标文件将包含重定位信息,在加载时需要重定位该符号,否则执行时将因找不到地址而出错 #ifdef DEBUG//开始是调试用,主要是一些打印输出函数,不用关心 #if defined(CONFIG_DEBUG_ICEDCC)

……具体代码略 #endif 宏定义结束之后定义了一个段, .section ".start", #alloc, #execinstr 这个段的段名是 .start,#alloc表示Section contains allocated data, #execinstr表示Section contains executable instructions. 生成最终映像时,这段代码会放在最开头 .align start: .type start,#function /*.type指定start这个符号是函数类型*/ .rept 8 mov r0, r0 //将此命令重复8次,相当于nop,这里是为中断向量保存空间 .endr b 1f .word 0x016f2818 @ Magic numbers to help the loader

Android USB 驱动分析

Android USB 驱动分析 一、USB驱动代码架构和使用 1、代码简介 USB驱动代码在/drivers/usb/gadget下,有三个文件:android.c, f_adb.c, f_mass_storage.c;g_android.ko 是由这三个文件编译而来,其中android.c 依赖于 f_adb.c 和 f_mass_storage.c(这两个文件之间无依赖关系)。 可在android.c中看到: static int __init android_bind_config(struct usb_configuration *c) { struct android_dev *dev = _android_dev; int ret; printk(KERN_DEBUG "android_bind_config\n"); ret = mass_storage_function_add(dev->cdev, c, dev->nluns); if (ret) return ret; return adb_function_add(dev->cdev, c); } 2、驱动使用 要使USB mass storage连接到主机: 打开/sys/devices/platform/usb_mass_storage/lun0/file文件,向 file文件写入一个存储 设备的路径,例如/dev/block/vold/179:0 (major:minor)路径; 这里的usb_mass_storage根据实际应用可以改的,由 platform_device_register函数的参数决 定。 例如: static struct platform_device fsg_platform_device = { .name = "usb_mass_storage", .id = -1, }; static void __init tegra_machine_init(void) { .... (void) platform_device_register(&fsg_platform_device); .... }

Android开机启动流程样本

Android的开机流程 1. 系统引导bootloader 1) 源码: bootable/bootloader/* 2) 说明: 加电后, CPU将先执行bootloader程序, 此处有三种选择 a) 开机按Camera+Power启动到fastboot, 即命令或SD卡烧写模式, 不加载内核及文件系统, 此处能够进行工厂模式的烧写 b) 开机按Home+Power启动到recovery模式, 加载recovery.img, recovery.img包含内核, 基本的文件系统, 用于工程模式的烧写 c) 开机按Power, 正常启动系统, 加载boot.img, boot.img包含内核, 基本文件系统, 用于正常启动手机( 以下只分析正常启动的情况) 2. 内核kernel 1) 源码: kernel/* 2) 说明: kernel由bootloader加载 3. 文件系统及应用init 1) 源码: system/core/init/* 2) 配置文件: system/rootdir/init.rc, 3) 说明: init是一个由内核启动的用户级进程, 它按照init.rc中的设置执行: 启动服务( 这里的服务指linux底层服务, 如adbd提供adb支持, vold提供SD卡挂载等) , 执行命令和按其中的配置语句执行相应功能 4. 重要的后台程序zygote 1) 源码: frameworks/base/cmds/app_main.cpp等 2) 说明: zygote是一个在init.rc中被指定启动的服务, 该服务对应的命令是/system/bin/app_process

Android 串口编程原理和实现方式附源码

提到串口编程,就不得不提到JNI,不得不提到JavaAPI中的文件描述符类:。下面我分别对JNI、以及串口的一些知识点和实现的源码进行分析说明。这里主要是参考了开源项目android-serialport-api。 串口编程需要了解的基本知识点:对于串口编程,我们只需对串口进行一系列的设置,然后打开串口,这些操作我们可以参考串口调试助手的源码进行学习。在Java中如果要实现串口的读写功能只需操作文件设备类:即可,其他的事都由驱动来完成不用多管!当然,你想了解,那就得看驱动代码了。这里并不打算对驱动进行说明,只初略阐述应用层的实现方式。 (一)JNI: 关于JNI的文章网上有很多,不再多做解释,想详细了解的朋友可以查看云中漫步的技术文章,写得很好,分析也很全面,那么在这篇拙文中我强调3点: 1、如何将编译好的SO文件打包到APK中?(方法很简单,直接在工程目录下新建文件夹libs/armeabi,将SO文件Copy到此目录即可) 2、命名要注意的地方?(在编译好的SO文件中,将文件重命名为:lib即可。其中是编译好后生成的文件) 3、MakeFile文件的编写(不用多说,可以直接参考package/apps目录下用到JNI的相关项目写法) 这是关键的代码: [cpp]view plaincopy

(二):

文件描述符类的实例用作与基础机器有关的某种结构的不透明句柄,该结构表示开放文件、开放套接字或者字节的另一个源或接收者。文件描述符的主要实际用途是创建一个包含该结构的或。这是API的描述,不太好理解,其实可简单的理解为:就是对一个文件进行读写。 (三)实现串口通信细节 1) 建工程:SerialDemo包名:org.winplus.serial,并在工程目录下新建jni和libs两个文件夹和一个org.winplus.serial.utils,如下图: 2) 新建一个类:SerialPortFinder,添加如下代码: [java]view plaincopy 1.package org.winplus.serial.utils; 2. 3.import java.io.File; 4.import java.io.; 5.import java.io.IOException; 6.import java.io.LineNumberReader; 7.import java.util.Iterator; 8.import java.util.Vector; 9. 10.import android.util.Log; 11. 12.public class SerialPortFinder { 13. 14.private static final String TAG = "SerialPort"; 15.

Android系统启动过程详解

Android系统启动过程详解 Android系统启动过程 首先Android框架架构图:(来自网上,我觉得这张图看起来很清晰) Linux内核启动之后就到Android Init进程,进而启动Android相关的服务和应用。 启动的过程如下图所示:(图片来自网上,后面有地址)

下面将从Android4.0源码中,和网络达人对此的总结中,对此过程加以学习了解和总结, 以下学习过程中代码片段中均有省略不完整,请参照源码。

一Init进程的启动 init进程,它是一个由内核启动的用户级进程。内核自行启动(已经被载入内存,开始运行, 并已初始化所有的设备驱动程序和数据结构等)之后,就通过启动一个用户级程序init的方式,完成引导进程。init始终是第一个进程。 启动过程就是代码init.c中main函数执行过程:system\core\init\init. c 在函数中执行了:文件夹建立,挂载,rc文件解析,属性设置,启动服务,执行动作,socket监听…… 下面看两个重要的过程:rc文件解析和服务启动。 1 rc文件解析 .rc文件是Android使用的初始化脚本文件(System/Core/Init/readm e.txt中有描述: four broad classes of statements which are Actions, Commands, Services, and Options.) 其中Command 就是系统支持的一系列命令,如:export,hostname,mkdir,mount,等等,其中一部分是linux 命令, 还有一些是android 添加的,如:class_start :启动服务,class_stop :关闭服务,等等。 其中Options是针对Service 的选项的。 系统初始化要触发的动作和要启动的服务及其各自属性都在rc脚本文件中定义。具体看一下启动脚本:\system\core\rootdir\init.rc 在解析rc脚本文件时,将相应的类型放入各自的List中: \system\core\init\Init_parser.c :init_parse_config_file( )存入到 action_queue、action_list、service_list中,解析过程可以看一下parse_config函数,类似状态机形式挺有意思。 这其中包含了服务:adbd、servicemanager、vold、ril-daemon、deb uggerd、surfaceflinger、zygote、media…… 2 服务启动 文件解析完成之后将service放入到service_list中。 文件解析完成之后将service放入到service_list中。 \system\core\init\builtins.c

Android SystemBar启动流程分析

Android SystemBar启动流程分析 SystemBars的服务被start时,最终会调用该类的onNoService()方法。 @Override public void start() { if (DEBUG) Log.d(TAG, "start"); ServiceMonitor mServiceMonitor = new ServiceMonitor(TAG, DEBUG, mContext, Settings.Secure.BAR_SERVICE_COMPONENT, this); mServiceMonitor.start(); // will call onNoService if no remote service is found } @Override public void onNoService() { if (DEBUG) Log.d(TAG, "onNoService"); createStatusBarFromConfig(); // fallback to using an in-process implementation } private void createStatusBarFromConfig() { … mStatusBar = (BaseStatusBar) cls.newInstance(); … mStatusBar.start(); } BaseStatusBar是一个抽象类,故调用其子类的PhoneStatusBar的start 函数。 @Override public void start() { … super.start(); … } 子类的start又调用了父类的start public void start() { … createAndAddWindows(); … }

App工程结构搭建:几种常见Android代码架构分析

App工程结构搭建:几种常见Android代码架构分析 关于Android架构,因为手机的限制,目前我觉得也确实没什么大谈特谈的,但是从开发的角度,看到整齐的代码,优美的分层总是一种舒服的享受的。 从艺术的角度看,其实我们是在追求一种美。 本文先分析几个当今比较流行的android软件包,最后我们汲取其中觉得优秀的部分,搭建我们自己的通用android工程模板。 1. 微盘 微盘的架构比较简单,我把最基本,最主干的画了出来: 第一层:com.sina.VDisk:com.sina(公司域名)+app(应用程序名称) 。 第二层:各模块名称(主模块VDiskClient和实体模块entities)第三层:各模块下具体子包,实现类。 从图中我们能得出上述分析中一个最简单最经典的结构,一般在应用程序包下放一些全局的包或者类,如果有多个大的模块,可以分成多个包,其中包括一个主模块。 在主模块中定义基类,比如BaseActivity等,如果主模块下还有子模块,可以在主模块下建立子模块相应的包。说明一点,有的时候如果只有一个主模块,我们完全可以省略掉模

块这一层,就是BaseActivity.java及其子模块直接提至第二层。 在实体模块中,本应该定义且只定义相应的实体类,供全局调用(然而实际情况可能不是这样,后面会说到)。在微盘应用中,几乎所有的实体类是以xxx+info命名的,这种命名也是我赞成的一种命名,从语义上我觉得xxxModel.java这种命名更生动更真实,xxxModel给我一种太机械太死板的感觉,这点完全是个人观点,具体操作中以个人习惯为主。还有一点,在具体的xxxInfo,java中有很多实体类中是没有get/set的方法,而是直接使用public的字段名。这一点,我是推荐这种方式的,特别是在移动开发中,get/set方法很多时候是完全没有必要的,而且是有性能消耗的。当然如果需要对字段设置一定的控制,get/set方法也是可以酌情使用的。 2. 久忆日记 相比于微盘的工程结构,久忆日记的结构稍微复杂了一些。如下图: 1).第一层和前面微盘一样的. 2).第二层则没有模块分类,直接把需要的具体实现类都放在下面,主要日记的一些日记相关的Activity。 3).第二层的实体包命令为model包,里面不仅存放了实体类

AndroidL系统启动及加载流程分析

Android L系统启动及加载流程分析 1、概述 Android L的启动可以分为几个步骤:Linux内核启动、init进程启动、native系统服务及java系统服务启动、Home启动,主要过程如下图: 图1 整个启动流程跟4.4及之前的版本相差不多,只是有个别不同之处,本文我们主要分析Linux内核启动之后的过程。

2、启动过程分析 2.1 init进程启动 当系统内核加载完成之后,会启动init守护进程,它是内核启动的第一个用户级进程,是Android的一个进程,进程号为1,init进程启动后执行入口函数main(),主要操作为: 图2 AndroidL上将selinux的安全等级提高了,设为了enforcing模式,4.4上是permissive模式。 解析rc脚本文件,即init.rc脚本,该文件是Android初始化脚本,定义了一系列的动作和执行这些动作的时间阶段e aryl-init、init、early-boot、boot、post-fs等阶段。init进程main 函数中会根据这些阶段进行解析执行。AndroidL上为了流程更清晰,增加了charger(充电开机)、ffbm(工厂模式)、以及late-init阶段,实际上这些阶段是对其他阶段的组合执行,比如late-init:

2.2 ServiceManager的启动 servicemanager的启动就是init进程通过init.rc脚本启动的: 源码在frameworks/native/cmds/servicemanager/service_manager.c中,servicemanager是服务管理器,它本身也是一个服务(handle=0),通过binder调用,为native和Java系统服务提供注册和查询服务的,即某个服务启动后,需要将自己注册到servicemanager中,供其他服务或者应用查询使用。AndroidL上servicemanger中在处理注册和查询动作之前添加了selinux安全检测相关的处理。 2.3 SurfaceFinger、MediaServer进程启动 Android4.4以前,surfacefinger的启动根据属性system_init.startsurfaceflinger,决定是通过init.rc启动还是systemserver进程启动,之后的版本包括AndoridL都是通过init.rc启动的: 启动后会向servicemanager进程注册服务中,该服务启动时主要功能是初始化整个显

android开机启动流程简单分析

android开机启动流程简单分析 android启动 当引导程序启动Linux内核后,会加载各种驱动和数据结构,当有了驱动以后,开始启动Android系统同时会加载用户级别的第一个进程init(system\core\init\init.cpp)代码如下: int main(int argc, char** argv) { ..... //创建文件夹,挂载 // Get the basic filesystem setup we need put together in the initramdisk // on / and then we'll let the rc file figure out the rest. if (is_first_stage) { mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755"); mkdir("/dev/pts", 0755); mkdir("/dev/socket", 0755); mount("devpts", "/dev/pts", "devpts", 0, NULL); #define MAKE_STR(x) __STRING(x) mount("proc", "/proc", "proc", 0, "hidepid=2,gid=" MAKE_STR(AID_READPROC)); mount("sysfs", "/sys", "sysfs", 0, NULL); } ..... //打印日志,设置log的级别 klog_init(); klog_set_level(KLOG_NOTICE_LEVEL); ..... Parser& parser = Parser::GetInstance(); parser.AddSectionParser("service",std::make_unique()); parser.AddSectionParser("on", std::make_unique()); parser.AddSectionParser("import", std::make_unique()); // 加载init.rc配置文件 parser.ParseConfig("/init.rc"); } 加载init.rc文件,会启动一个Zygote进程,此进程是Android系统的一个母进程,用来启动Android的其他服务进程,代码: 从Android L开始,在/system/core/rootdir 目录中有4 个zygote 相关的启动脚本如下图:

最全的Android源码目录结构详解

最全的Android源码目录结构详解 Android 2.1 |-- Makefile |-- bionic (bionic C库) |-- bootable (启动引导相关代码) |-- build (存放系统编译规则及generic等基础开发包配置) |-- cts (Android兼容性测试套件标准) |-- dalvik (dalvik JAVA虚拟机) |-- development (应用程序开发相关) |-- external (android使用的一些开源的模组) |-- frameworks (核心框架——java及C++语言) |-- hardware (部分厂家开源的硬解适配层HAL代码) |-- out (编译完成后的代码输出与此目录) |-- packages (应用程序包) |-- prebuilt (x86和arm架构下预编译的一些资源) |-- sdk (sdk及模拟器) |-- system (底层文件系统库、应用及组件——C语言) `-- vendor (厂商定制代码) bionic 目录 |-- libc (C库) | |-- arch-arm (ARM架构,包含系统调用汇编实现) | |-- arch-x86 (x86架构,包含系统调用汇编实现) | |-- bionic (由C实现的功能,架构无关) | |-- docs (文档) | |-- include (头文件) | |-- inet (?inet相关,具体作用不明) | |-- kernel (Linux内核中的一些头文件) | |-- netbsd (?nesbsd系统相关,具体作用不明) | |-- private (?一些私有的头文件) | |-- stdio (stdio实现) | |-- stdlib (stdlib实现) | |-- string (string函数实现) | |-- tools (几个工具) | |-- tzcode (时区相关代码) | |-- unistd (unistd实现) | `-- zoneinfo (时区信息) |-- libdl (libdl实现,dl是动态链接,提供访问动态链接库的功能)|-- libm (libm数学库的实现,) | |-- alpha (apaha架构) | |-- amd64 (amd64架构) | |-- arm (arm架构) | |-- bsdsrc (?bsd的源码)

相关文档
相关文档 最新文档