• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >Android > Android深入四大组件(一)应用程序启动过程

Android深入四大组件(一)应用程序启动过程

作者:刘望舒的专栏 字体:[增加 减小] 来源:互联网 时间:2017-07-23

刘望舒的专栏通过本文主要向大家介绍了四大组件,应用程序启动,Launcher等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

相关文章
Android系统架构与系统源码目录
Android系统启动流程(一)解析init进程启动过程
Android系统启动流程(二)解析Zygote进程启动过程
Android系统启动流程(三)解析SyetemServer进程启动过程
Android系统启动流程(四)Launcher启动过程与系统启动流程
Android应用程序进程启动过程(前篇)
Android应用程序进程启动过程(后篇)

前言

在此前的文章中,我讲过了Android系统启动流程和Android应用进程启动过程,这一篇顺理成章来学习Android 7.0的应用程序的启动过程。分析应用程序的启动过程其实就是分析根Activity的启动过程。

1.Launcher请求ActivityManageService

在 Android系统启动流程(四)Launcher启动过程与系统启动流程这篇文章我讲过Launcher启动后会将已安装应用程序的快捷图标显示到界面上,当我们点击应用程序的快捷图标时就会调用Launcher的startActivitySafely方法,如下所示。
packages/apps/Launcher3/src/com/android/launcher3/Launcher.java

  public boolean startActivitySafely(View v, Intent intent, Object tag) {
      ...
        try {
            success = startActivity(v, intent, tag);
        } catch (ActivityNotFoundException e) {
            Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
            Log.e(TAG, "Unable to launch. tag=" + tag + " intent=" + intent, e);
        }
        return success;
    }

startActivitySafely函数中主要就是调用了startActivity函数:
packages/apps/Launcher3/src/com/android/launcher3/Launcher.java

 private boolean startActivity(View v, Intent intent, Object tag) {
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//1
        try {
          ...
            if (user == null || user.equals(UserHandleCompat.myUserHandle())) {
                StrictMode.VmPolicy oldPolicy = StrictMode.getVmPolicy();
                try {            
                    StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectAll()
                            .penaltyLog().build());
                    startActivity(intent, optsBundle);//2
                } finally {
                    StrictMode.setVmPolicy(oldPolicy);
                }
            } else {
                launcherApps.startActivityForProfile(intent.getComponent(), user,
                        intent.getSourceBounds(), optsBundle);
            }
            return true;
        } catch (SecurityException e) {      
          ...
        }
        return false;
    }

在注释1处设置Flag为Intent.FLAG_ACTIVITY_NEW_TASK,这样根Activity会在新的任务栈中启动。在注释2处调用了startActivity函数:
frameworks/base/core/java/android/app/Activity.java

Override
public void startActivity(Intent intent, @Nullable Bundle options) {
    if (options != null) {
        startActivityForResult(intent, -1, options);
    } else {
        startActivityForResult(intent, -1);
    }
}

startActivity会调用startActivityForResult函数,其中第二个参数为-1,表示Launcher不需要知道Activity启动的结果,startActivityForResult函数的代码如下所示。
frameworks/base/core/java/android/app/Activity.java

 public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
            @Nullable Bundle options) {
        if (mParent == null) {
            Instrumentation.ActivityResult ar =
                mInstrumentation.execStartActivity(
                    this, mMainThread.getApplicationThread(), mToken, this,
                    intent, requestCode, options);
         ...
        } else {
         ...
        }
    }

mParent是Activity类型的,表示当前Activity的父类。因为目前根Activity还没有创建出来,因此,mParent == null成立。接着调用Instrumentation的execStartActivity方法,Instrumentation主要用来监控应用程序和系统的交互,execStartActivity方法的代码如下所示。
frameworks/base/core/java/android/app/Instrumentation.java

public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
      ...
        try {
            intent.migrateExtraStreamToClipData();
            intent.prepareToLeaveProcess(who);
            int result = ActivityManagerNative.getDefault()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target != null ? target.mEmbeddedID : null,
                        requestCode, 0, null, options);
            checkStartActivityResult(result, intent);
        } catch (RemoteException e) {
            throw new RuntimeException("Failure from system", e);
        }
        return null;
    }

首先会调用ActivityManagerNative的getDefault来获取ActivityManageService(以后简称为AMS)的代理对象,接着调用它的startActivity方法。首先我们先来查看ActivityManagerNative的getDefault方法做了什么:
frameworks/base/core/java/android/app/ActivityManagerNative.java

  static public IActivityManager getDefault() {
        return gDefault.get();
    }

    private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
        protected IActivityManager create() {
            IBinder b = ServiceManager.getService("activity");//1
            if (false) {
                Log.v("ActivityManager", "default service binder = " + b);
            }
            IActivityManager am = asInterface(b);//2
            if (false) {
                Log.v("ActivityManager", "default service = " + am);
            }
            return am;
        }
    };
}

getDefault方法调用了gDefault的get方法,我们接着往下看,gDefault 是一个Singleton类。注释1处得到名为”activity”的Service代理对象,也就是ActivityManagerService的代理对象。接着在注释2处将它封装成ActivityManagerProxy(以后简称为AMP)类型对象,并将它保存到gDefault中,此后调用ActivityManagerNative的getDefault方法就会直接获得AMS的代理AMP对象。
回到Instrumentation类的execStartActivity方法中,从上面得知就是调用AMP的startActivity,其中AMP是ActivityManagerNative的内部类,代码如下所示。
frameworks/base/core/java/android/app/ActivityManagerNative.java

 public int startActivity(IApplicationThread caller, String callingPackage, Intent intent,
            String resolvedType, IBinder resultTo, String resultWho, int requestCode,
            int startFlags, ProfilerInfo profilerInfo, Bundle options) throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IActivityManager.descriptor);
        data.writeStrongBinder(caller != null ? caller.asBinder() : null);
        data.writeString(callingPackage);
        intent.writeToParcel(data, 0);
        data.writeString(resolvedType);
        data.writeStrong



 
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • Android深入四大组件(五)ContentProvider的启动过程
  • Android深入四大组件(四)广播的注册、发送和接收过程
  • Android深入四大组件(一)应用程序启动过程
  • Android中使用findViewByMe提升组件查找效率,光伏组件转换效率
  • 安卓高级组件-----网格视图,安卓-----网格
  • 安卓高级组件-----图像切换器,安卓-----切换器
  • 安卓高级组件-----进度条,安卓-----进度条
  • 安卓界面高级组件------拖动条和评星条,安卓------拖动
  • 安卓界面组件----时间日期拾取器,安卓拾取
  • 安卓界面基本组件------计时器,安卓------计时器

相关文章

  • 2017-05-26初涉RxAndroid结合Glide实现多图片加载操作
  • 2017-05-26android开发零基础入门教程,android入门教程
  • 2017-08-23Glide中request的调用和管理
  • 2017-05-26深入了解Kotlin的必备书籍,深入了解kotlin必备
  • 2017-05-26『BUG』Android Studio 64位 始终提示 JVM 启动不了,JDK配置失败,error code,androidjvm
  • 2017-05-26一次奇怪的MySQL复制故障
  • 2017-05-26安卓第十八天笔记--简单动画,安卓第十八天--
  • 2017-05-26安卓界面高级组件------拖动条和评星条,安卓------拖动
  • 2017-05-26Android的消息机制,Android消息机制
  • 2017-05-26Unity实现滑页嵌套(解决ScrollRect嵌套冲突问题)

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • Android.mk模板(持续更新中),android.mk更新中
    • Android常见问题及开发经验总结(三)
    • 贝塞尔曲线实现的购物车添加商品动画效果,贝塞尔购物车
    • 上传单个文件到多台机器工具
    • 组件RecyclerView的应用(一),组件recyclerview
    • 关于安卓APP的启动界面,安卓APP启动界面
    • 硅谷社交8--联系人列表页面,硅谷社交8--联系人
    • Android studio使用gradle动态构建APP(不同的包,不同的icon、label),androidgradle
    • Linux常用命令-50:crontab命令
    • Android 如何本地加载pdf文件,android加载pdf

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有