皮皮网
皮皮网

【apifox源码】【c文件编译源码】【阳江旅行世界源码】activity 启动源码_activity启动原理

来源:ssm框架源码教程 发表时间:2024-11-29 00:25:59

1.Python 脚本收集 Activity 启动时间
2.Android源码阅读分析:ActivityManagerService分析(一)——启动流程
3.activity的启动启动生命周期和启动模式是什么?
4.Android Framework源码面试——Activity启动流程
5.Android Activity Deeplink启动来源获取源码分析
6.Android N 四大组件的工作原理

activity 启动源码_activity启动原理

Python 脚本收集 Activity 启动时间

       使用场景包括启动应用程序或其中的某个页面。

       完整命令是源码原理:adb shell am start -W com.coral.aop/.hook.HookInstrumentationActivity

       此命令通过adb执行手机中/system/bin目录下的shell脚本,而am命令则执行同目录下的启动启动am脚本文件。通过adb shell am ls /system/bin命令可列出该目录下所有脚本文件。源码原理其他命令请查阅官方adb命令文档。启动启动

       查看am脚本内容:#!/system/bin/sh,源码原理apifox源码如果输入参数非"instrument",启动启动执行cmd activity "$@";否则将base设为/system,源码原理export CLASSPATH=$base/framework/am.jar,启动启动执行app_process $base/bin com.android.commands.am.Am "$@"。源码原理

       该脚本主要通过app_process命令启动framework下的启动启动am.jar包中Am类入口的main()方法。确认该脚本功能需查看Framework底层源码,源码原理代码库可从GitHub下载。启动启动app_process主要启动zygote或Java程序,源码原理通过定位cmds/am/com/android/commands/am/Am.java,启动启动分析源码得知am start命令启动Activity。

       总结,通过am start启动应用中的某个页面,最终通过AMS启动并管理Activity。am start -W命令启动应用后,终端输出参数含义如下:Starting:启动Activity的c文件编译源码Intent;Status:timeout或ok;Activity:启动的Activity(如果在onCreate销毁或crash则为下一个展示的Activity);ThisTime:表示一连串Activity的最后一个Activity的启动耗时;TotalTime:表示新应用启动耗时,包括新进程启动和Activity启动;WaitTime:总耗时,包括前一个应用Activity pause时间和新应用启动时间。

Android源码阅读分析:ActivityManagerService分析(一)——启动流程

       本文深入解析了Android源码中的ActivityManagerService,即AMS的核心功能与启动流程。AMS作为管理Android四大组件的关键组件,其重要性不言而喻。本篇将从AMS的创建与启动逻辑开始分析,为理解其内部机制打下基础。

       AMS的创建始于SystemServer的startBootstrapServices方法。此方法通过SystemServiceManager的startService方法启动Lifecycle类实例,从而创建AMS对象。Lifecycle作为适配器,连接了AMS与SystemService之间的交互。再通过Lifecycle的构造器,创建出AMS实例。

       创建过程中,AMS线程、UI线程、CpuTracker线程和系统目录被初始化,同时StackSupervisor与ActivityStarter也得以创建,阳江旅行世界源码完成AMS对象的创建。

       随后,ActivityManagerService的startService(SystemService)方法执行,完成服务的注册与启动。Lifecycle的onStart方法调用ActivityManagerService的start方法,启动关键操作。

       在SystemServer的startBootstrapServices方法中,创建完AMS后,执行其setSystemProcess方法,为系统进程启动Application实例与服务注册。然后,SystemServer继续调用startBootstrapServices、startCoreServices与startOtherServices方法,启动更多系统服务与持久化进程,完成桌面Activity的启动与广播发布。

       文中总结了AMS创建与启动的关键步骤,并预告后续文章将深入探讨AMS的具体使用、对四大组件的管理以及内存管理等内容。通过本篇解析,读者能更直观地理解Android系统中AMS的软件rsi源码公式核心功能与作用。

activity的生命周期和启动模式是什么?

       本文深入探讨了Android中Activity的生命周期和启动模式,旨在帮助开发者更全面地理解这两个关键概念。

       首先,让我们聚焦Activity的生命周期方法,这些方法在特定的事件触发时执行。在普通情况下,Activity生命周期的执行顺序通常遵循一个标准流程。当屏幕横竖屏切换时,Activity的生命周期会呈现不同的执行顺序。在横竖屏切换时,Activity先被销毁后重建,执行过程中涉及`onPause()`、`onSaveInstanceState()`、`onStart()`和`onRestoreInstanceState()`方法。在销毁时,`onSaveInstanceState()`被调用,开发者有机会保存需要恢复的信息。当Activity重建时,`onRestoreInstanceState()`接收在前一次执行时保存的信息,用于恢复必要的宜昌直播源码开发数据。

       当系统内存不足导致低优先级的Activity被回收时,生命周期方法的执行顺序与横竖屏切换时相似,同样会执行`onSaveInstanceState()`和`onRestoreInstanceState()`方法,以确保数据的完整性和恢复性。

       接下来,我们探讨Activity的四种启动模式,这些模式影响了Activity在任务栈中的行为。默认情况下,使用`ApplicationContext`启动`standard`模式的Activity会导致错误,因为此模式的Activity默认会进入启动它的Activity所属的任务栈,而非使用`Activity`类型的`Context`时的情况。解决这一问题的关键是通过指定`FLAG_ACTIVITY_NEW_TASK`标志在使用`ApplicationContext`启动Activity时,这样创建一个新栈以正确地启动Activity。

       在理解了`singleInstance`和`singleTask`的区别之后,我们发现它们在启动行为上存在显著差异。`singleTask`模式允许在启动新的`Activity`时,如果目标`Activity`已经在栈中存在,则直接使用栈顶的实例,而不会重新创建新的实例。相比之下,`singleInstance`模式在启动Activity时会创建一个新的任务栈,并且在栈顶创建实例,确保每次启动时都是新实例。

       本文最后推荐了由阿里高级架构师编写的《Android八大模块进阶资料》,该资料旨在帮助开发者系统化整理和掌握Android开发的知识点。资料以PDF文档的形式提供,包含由资深专家精心编写的笔记和源码解析合集、开源框架合集等内容。通过这套资料,开发者能够更深入地理解Android开发的各个方面,从而提高编程效率和代码质量。

Android Framework源码面试——Activity启动流程

       面试官常问关于Activity启动模式的问题,但这涉及的知识点远不止四种模式。默认启动模式会因Intent Flag的设置而发生变化,面试时仅凭流程描述往往难以全面理解。

       设置FLAG_ACTIVITY_NEW_TASK在Service中启动Activity时,Activity的启动行为会有所不同。不同场景下,Activity的启动表现各不相同。以singleInstance属性为例,即使设置了,使用Intent.FLAG_ACTIVITY_CLEAR_TASK启动时,并非完全遵循只复用实例的原则。

       此外,不同Intent Flag的叠加使用也有各自的特性和表现。单一讨论启动模式的原理不易全面,理解需要结合实际项目、阅读源码或实验验证。

       面试中,面试官可能会提出深入的、场景化的关于Activity启动的问题。例如,在Service中启动Activity时,FLAG_ACTIVITY_NEW_TASK的作用是什么?设置singleInstance后,使用FLAG_ACTIVITY_CLEAR_TASK启动时的行为如何?不同Intent Flag的组合使用又会产生哪些不同的结果?

       理解这些知识点不仅需要对Android框架有深入的了解,还需要通过实践去验证和理解。比如,尝试在实际项目中使用不同的Intent Flag,观察Activity的启动行为,这样能更好地理解其背后的原理。

Android Activity Deeplink启动来源获取源码分析

       Deeplink在业务模块中作为外部应用的入口提供,不同跳转类型可能会导致应用提供不一致的服务,通常通过反射调用Activity中的mReferrer字段获取跳转来源的包名。然而,mReferrer存在被伪造的风险,可能导致业务逻辑出错或经济损失。因此,我们需要深入分析mReferrer的来源,并寻找更为安全的获取方法。

       为了深入了解mReferrer的来源,我们首先使用搜索功能在Activity类中查找mReferrer,发现其在Attach方法中进行赋值。进一步通过断点调试跟踪调用栈,发现Attach方法是由ActivityThread.performLaunchActivity调用的。而performLaunchActivity在调用Attach时,传入的referrer参数实际上是一个ActivityClientRecord对象的referrer属性。深入分析后,发现referrer是在ActivityClientRecord的构造函数中被赋值的。通过进一步的调试发现,ActivityClientRecord的实例化来自于LaunchActivityItem的mReferrer属性。接着,我们分析了mReferrer的来源,发现它最终是由ActivityStarter的setCallingPackage方法注入的。而这个setCallingPackage方法的调用者是ActivityTaskManagerService的startActivity方法,进一步追踪调用链路,我们发现其源头是在App进程中的ActivityTaskManager.getService()方法调用。

       在分析了远程服务Binder调用的过程后,我们发现获取IActivityTaskManager.Stub的方法是ActivityTaskManager.getService()。这使得我们能够追踪到startActivity方法的调用,进而找到发起Deeplink的应用调用的具体位置。通过这个过程,我们确定了mReferrer实际上是通过Activity的getBasePackageName()方法获取的。

       为了防止包名被伪造,我们注意到ActivityRecord中还包含PID和Uid。通过使用Uid结合包管理器的方法来获取对应的包名,可以避免包名被伪造。通过验证Uid的来源,我们发现Uid实际上是通过Binder.getCallingUid方法获取的,且Binder进程是无法被应用层干涉的,因此Uid是相对安全的。接下来,我们可以通过Uid来置换包名,进一步提高安全性。

       总结,mReferrer容易被伪造,应谨慎使用。通过使用Uid来获取包名,可以提供一种更为安全的获取方式。此过程涉及对源代码的深入分析和调试,作者Chen Long为vivo互联网客户端团队成员。

Android N 四大组件的工作原理

       æœ¬æ–‡ä¾§é‡è®²è§£android N 系统中四大组件的工作原理,不同系统原理略有差别。通过分析四大组件的工作流程加深对Android Framework的理解,也为插件化开发打下基础。

        Activity

        展示一个界面并和用户交互,它扮演的是一个前台界面的角色。

        Service

        计算型组件,用于后台执行一系列计算任务,工作在主线程,耗时操作需要另起线程, 分为启动状态和绑定状态。

        BroadcastReceiver

        消息型组件,主要用于不同组件或者不同应用之间的消息传递,它工作在系统内部,不适合执行耗时操作,操作超过5s,会出现ANR。

        ContentProvider

        数据共享型组件,用于向其他组件或者应用共享数据,主要执行CURD操作。

        我们启动一个activity有两种方法,

        第一种(Activity直接启动方式):

        Intent intent = new Intent(this, MainActivity.class);

        startActivity(intent);

        第二种(Context启动方式)

        Intent intent = new Intent(this, MainActivity.class);

        getApplicationContext().startActivity(intent);

        不同的启动方式Activity的工作流程有点差别。

        两种启动都会调用到Instrumentation类中的execStartActivity的方法,系统最终是通过ActivityThread中的performLaunchActivity完成Activity的创建和启动。

        performLaunchActivity方法主要完成以下工作:

        1、通过ActivityClientRecord对象获取启动activity的组件信息

        2、通过mInstrumentation对象的newActivity方法调用classloader完成activity的创建

        3、通过r.packageInfo(LoadedApk 对象)的makeApplication方法尝试创建Application对象

        4、创建ContextImpl对象并调用Activity的attach方法完成一些数据的初始化

        5、调用Activity的onCreate方法

        在Activity启动的过程中,App进程会频繁地与AMS进程进行通信:

        App进程会委托AMS进程完成Activity生命周期的管理以及任务栈的管理;这个通信过程AMS是Server端,App进程通过持有AMS的client代理IActivityManager完成通信过程;

        AMS进程完成生命周期管理以及任务栈管理后,会把控制权交给App进程,让App进程完成Activity类对象的创建,以及生命周期回调;这个通信过程也是通过Binder完成的,App所在server端的Binder对象存在于ActivityThread的内部类ApplicationThread;AMS所在client通过持有IApplicationThread的代理对象完成对于App进程的通信。

        Service有两种启动方式,startService()和bindService(),两种状态可以并存:

        startService流程

        bindService流程

        BroadcastReceiver的工作过程主要包括广播的注册、发送和接收:

        动态注册过程:

        发送过程

        静态注册是由PackageManagerService(PMS)在应用安装的时候完成整个注册过程的,除广播以外,其他三大组件也都是在应用安装时由PMS解析并注册的。

        每个进程的入口都是ActivityThead.main(),App的启动流程如下:

        从源码中可以看出:

        应用启动的入口为ActivityThread的main方法,main方法会创建ActivityThread实例并创建主线程消息队列。

        attach方法中远程调用AMS的attachApplication方法,并提供ApplicationThread用于和AMS的通信。

        attachApplication方法会通过bindApplication方法和H来调回ActivityThread的handleBindApplication,这个方法会先创建Application,再加载ContentProvider,然后才会回调Application的onCreate方法。

        由上图可以看出,在ContentProvider的启动过程中伴随着app进程的启动。

        ContentProvider的其他CURD操作如insert,delete,update跟query的流程类似。

Activity的基础知识(下)

       ä¸Šç¯‡æ€»ç»“了Activity的一些知识,现在继续对Activity的知识进行梳理,包括Activity直接传递数据,Activity的生命周期,Activity的启动模式等.

        1.intent传递数据:

        使用startActivity方法,intent的putExtra()方法,以键值对的形式传递数据,该方法有很多重载方法,可以根据传递数据的不同类型选择合适的方法.除了有putExtra()方法外,还有putExtras()方法,传递的参数是Bundle.

        如果传递的是对象,这个对象要实现序列化,也就是实现Parcelable或者Serializable接口.

        如果希望被启动的页面返回数据,需要使用startActivityForResult()方法,这个方法中需要设置访问号,用来区分不同的访问者.并且在启动页重写onActivityResult方法用来接收返回的数据,

        2.两种情况下的Activity的生命周期.

        正常情况下的生命周期,正常情况是指用户的正常操作下的Activity的生命周期.后面会分析异常情况下的生命周期.

        onCreate: Activity第一次创建时候的回调,主要是在这个方法进行初始化工作,比如初始化控件和事件绑定工作.

        onStart:Activity从不可见状态变成可见状态.

        onResume:Activity变成前台,可以和用户交互.

        onPause:Activity可见但是不能和用户交互.

        onStop:Activity从可见变得不可见,成为后台Activity.

        onDestroy:Activity销毁时调用.

        onRestart:Activity从后台变成前台Activity.

        在启动Activity和两个Activity之间跳转时,可以知道Activity的生命周期变化过程,有两个说明:(1)在两个Activity跳转时,第一个Activty的onPause,onStop方法和第二个Activity的生命周期方法调用时机.

        第一个Activity先执行onPause方法,第二个Activity才能创建.这也就意味着在onPause方法中不能执行太耗时的操作,否则会影响第二个Activity的创建.在源码(ActivityStack)中有这样的注释:

        (2)onStart和onResume,onPause和onStop这两对方法的实质不同处:onStart和onStop这两个方法是从Activity的可见性来区分的,onResume和onPause是从Activity是否处于前台,是否可以和用户交互来区分的,注意在onPause调用时Activity还是可见的,调用时机比如弹出dialog时,下面的Activity是可见的.这个时候调用的是onPause方法.

        异常情况下Activity的生命周期:异常情况下是指资源相关配置发生变化或后台Activity被系统回收时Activity的生命周期.后台Activity被系统回收的情况比较难复现,在资源相关配置发生变化时和后台Activity被回收时的生命周期执行过程是一样的,比较容易复现的就是横竖屏切换时的生命周期执行过程.在 AndroidManifest的Activity组件下配置android:screenOrientation标签,当设置可以横竖方向随着方向感应器来调节时,在切换时会出现先销毁Activity再创建的过程.

        过程:

        在这种情况下有可能会有数据的丢失,系统提供用来保存数据和还原数据的方法:onSaveInstanceState和onRestoreInstanceState.用方法参数Bundle可以保存和还原数据.

        可以根据需要设置android:screenOrientation标签,设定activity的方向,如果activity的方向是需要横竖屏切换,但是不容许销毁Activity,可以设置如下标签,当这些情况(常用的)发生变化是不会重新走Activity的生命周期方法,只会调用onConfigurationChanged,可以根据情况在这个方法里更新操作.

        切换时的log输出

        3.Activity的四种启动模式

        标准:是Activity的默认启动模式,对于AndroidManifest的Activity节点下的android:launchMode="standard"标签.

        特定:每次启动都会重新创建新的Activity.

        singleTop:对应的AndroidManifes的Activity节点下的android:launchMode="singleTop"标签

        特点:当此模式的Activity处于栈顶时,不会重新创建新的Activity,会调用onNewIntent方法,如果更新Activity的intent,需要调用 setIntent()方法,具体的生命周期过程

        singleTask:在activity栈中已经有需要再启动的activity时,会先清除位于需要启动activity之上的activity,例如:启动顺序mainActivity-activityA -activityB-activityA,其中activityA是singleTask的启动模式:

        singleInstance:在一个栈中单独存在的activity.

        关于activity栈:是指用来管理activity一种"先进先出"的队列结构,查看activity对应栈的方法:Activity的getTaskId()方法,同一个栈的id值是相同的.adb shell dumpsys activity在终端查看栈结构,比如还是上面的activity启动顺序,不同是ActivityA这是设置成singleInstance,这是的栈结构:有两个TaskRecord,其中ActivityB和MainActivity位于同一个栈中.

        4.Activity开发中使用技巧:

        <1>定义一个父Activity,在创建新的Activity时继承这个activity即可,将一些activity的公共设置可以设置在父activity中,比如获取每个Activity的名字,设置activity的窗体属性,同一管理activity的生命周期等,

        <2>在启动的activity中定义静态方法,启动条件会显而易见:

        <3>管理activityç±»,用来一键退出app.在父类Activity的创建和销毁时用来添加和移除Activity,在需要一键退出的地方调用静态finishAllActivity方法.

相关栏目:百科