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

上传人:b****5 文档编号:5842730 上传时间:2023-01-01 格式:DOCX 页数:71 大小:90.14KB
下载 相关 举报
Android程序启动过程源码分析.docx_第1页
第1页 / 共71页
Android程序启动过程源码分析.docx_第2页
第2页 / 共71页
Android程序启动过程源码分析.docx_第3页
第3页 / 共71页
Android程序启动过程源码分析.docx_第4页
第4页 / 共71页
Android程序启动过程源码分析.docx_第5页
第5页 / 共71页
点击查看更多>>
下载资源
资源描述

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

《Android程序启动过程源码分析.docx》由会员分享,可在线阅读,更多相关《Android程序启动过程源码分析.docx(71页珍藏版)》请在冰豆网上搜索。

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

Android程序启动过程源码分析

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

分类:

Android2011-08-1900:

585447人阅读评论(40)收藏举报

     前文简要介绍了Android应用程序的Activity的启动过程。

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

     在上一篇文章Android应用程序的Activity启动过程简要介绍和学习计划中,我们举例子说明了启动Android应用程序中的Activity的两种情景,其中,在手机屏幕中点击应用程序图标的情景就会引发Android应用程序中的默认Activity的启动,从而把应用程序启动起来。

这种启动方式的特点是会启动一个新的进程来加载相应的Activity。

这里,我们继续以这个例子为例来说明Android应用程序的启动过程,即MainActivity的启动过程。

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

点击查看大图

     下面详细分析每一步是如何实现的。

     Step1.Launcher.startActivitySafely

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

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

viewplaincopytoclipboardprint?

1./** 

2.* Default launcher application. 

3.*/  

4.public final class Launcher extends Activity  

5.        implements View.OnClickListener, OnLongClickListener, LauncherModel.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.}  

     回忆一下前面一篇文章Android应用程序的Activity启动过程简要介绍和学习计划说到的应用程序Activity,它的默认Activity是MainActivity,这里是AndroidManifest.xml文件中配置的:

viewplaincopytoclipboardprint?

1.

name=".MainActivity"    

2.      android:

label="@string/app_name">    

3.           

4.        

name="android.intent.action.MAIN" />    

5.        

name="android.intent.category.LAUNCHER" />    

6.        

7.    

     因此,这里的intent包含的信息为:

action="android.intent.action.Main",category="android.intent.category.LAUNCHER",cmp="shy.luo.activity/.MainActivity",表示它要启动的Activity为shy.luo.activity.MainActivity。

Intent.FLAG_ACTIVITY_NEW_TASK表示要在一个新的Task中启动这个Activity,注意,Task是Android系统中的概念,它不同于进程Process的概念。

简单地说,一个Task是一系列Activity的集合,这个集合是以堆栈的形式来组织的,遵循后进先出的原则。

事实上,Task是一个非常复杂的概念,有兴趣的读者可以到官网

     Step2.Activity.startActivity

     在Step1中,我们看到,Launcher继承于Activity类,而Activity类实现了startActivity函数,因此,这里就调用了Activity.startActivity函数,它实现在frameworks/base/core/java/android/app/Activity.java文件中:

viewplaincopytoclipboardprint?

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.}  

     这个函数实现很简单,它调用startActivityForResult来进一步处理,第二个参数传入-1表示不需要这个Actvity结束后的返回结果。

     Step3. Activity.startActivityForResult

     这个函数也是实现在frameworks/base/core/java/android/app/Activity.java文件中:

viewplaincopytoclipboardprint?

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.}  

     这里的mInstrumentation是Activity类的成员变量,它的类型是Intrumentation,定义在frameworks/base/core/java/android/app/Instrumentation.java文件中,它用来监控应用程序和系统的交互。

     这里的mMainThread也是Activity类的成员变量,它的类型是ActivityThread,它代表的是应用程序的主线程,我们在Android系统在新进程中启动自定义服务过程(startService)的原理分析一文中已经介绍过了。

这里通过mMainThread.getApplicationThread获得它里面的ApplicationThread成员变量,它是一个Binder对象,后面我们会看到,ActivityManagerService会使用它来和ActivityThread来进行进程间通信。

这里我们需注意的是,这里的mMainThread代表的是Launcher应用程序运行的进程。

     这里的mToken也是Activity类的成员变量,它是一个Binder对象的远程接口。

     Step4.Instrumentation.execStartActivity

     这个函数定义在frameworks/base/core/java/android/app/Instrumentation.java文件中:

viewplaincopytoclipboardprint?

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 :

 null,  

17.                requestCode, false, false);  

18.            ......  

19.        } catch (RemoteException e) {  

20.        }  

21.        return null;  

22.    }  

23.  

24.    ......  

25.  

26.}  

     这里的ActivityManagerNative.getDefault返回ActivityManagerService的远程接口,即ActivityManagerProxy接口,具体可以参考Android系统在新进程中启动自定义服务过程(startService)的原理分析一文。

     这里的intent.resolveTypeIfNeeded返回这个intent的MIME类型,在这个例子中,没有AndroidManifest.xml设置MainActivity的MIME类型,因此,这里返回null。

     这里的target不为null,但是target.mEmbddedID为null,我们不用关注。

     Step5.ActivityManagerProxy.startActivity

     这个函数定义在frameworks/base/core/java/android/app/ActivityManagerNative.java文件中:

viewplaincopytoclipboardprint?

1.class ActivityManagerProxy implements IActivityManager  

2.{  

3.  

4.    ......  

5.  

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

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

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.}  

     这里的参数比较多,我们先整理一下。

从上面的调用可以知道,这里的参数resolvedType、grantedUriPermissions和resultWho均为null;参数caller为ApplicationThread类型的Binder实体;参数resultTo为一个Binder实体的远程接口,我们先不关注它;参数grantedMode为0,我们也先不关注它;参数requestCode为-1;参数onlyIfNeeded和debug均空false。

     Step6.ActivityManagerService.startActivity

     上一步Step5通过Binder驱动程序就进入到ActivityManagerService的startActivity函数来了,它定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:

viewplaincopytoclipboardprint?

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[] grantedUriPermissions,  

8.            int grantedMode, IBinder resultTo,  

9.            String resultWho, int requestCode, boolean onlyIfNeeded,  

10.            boolean debug) {  

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

12.            grantedUriPermissions, grantedMode, resultTo, resultWho,  

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

14.    }  

15.  

16.  

17.    ......  

18.  

19.}  

     这里只是简单地将操作转发给成员变量mMainStack的startActivityMayWait函数,这里的mMainStack的类型为ActivityStack。

  

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高中教育 > 数学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1