1.Android Framework源码面试——Activity启动流程
2.Android Activity Deeplink启动来源获取源码分析
3.anfroid开发怎么查看某个类或方法的源码源代码
4.Android-Fragment源码分析
5.Android N å大ç»ä»¶çå·¥ä½åç
Android Framework源码面试——Activity启动流程
面试官常问关于Activity启动模式的问题,但这涉及的源码知识点远不止四种模式。默认启动模式会因Intent Flag的源码设置而发生变化,面试时仅凭流程描述往往难以全面理解。源码
设置FLAG_ACTIVITY_NEW_TASK在Service中启动Activity时,源码Activity的源码捕鱼比赛源码启动行为会有所不同。不同场景下,源码Activity的源码启动表现各不相同。以singleInstance属性为例,源码即使设置了,源码使用Intent.FLAG_ACTIVITY_CLEAR_TASK启动时,源码并非完全遵循只复用实例的源码原则。
此外,源码不同Intent Flag的源码叠加使用也有各自的特性和表现。单一讨论启动模式的源码原理不易全面,理解需要结合实际项目、阅读源码或实验验证。
面试中,面试官可能会提出深入的google chrome源码、场景化的关于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的web库存源码来源,并寻找更为安全的获取方法。
为了深入了解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来置换包名,进一步提高安全性。
总结,mmcv源码编译mReferrer容易被伪造,应谨慎使用。通过使用Uid来获取包名,可以提供一种更为安全的获取方式。此过程涉及对源代码的深入分析和调试,作者Chen Long为vivo互联网客户端团队成员。
anfroid开发怎么查看某个类或方法的源代码
android开发语言是java,由于java面向对象的特性,我们在开发中会非常多的用到继承重写等语言特性,一些内置类或方法在使用时需要我们重写或继承才能实现自定义,此时需要我们通过查看源代码来了解该函数或类的写法和用法。下面我们学习如何查看源代码。首先要先下载并安装好sdk源码,才可以查看。打开sdk manager
找到你的sdk已安装的最新的API版本,点击小三角,打开该API的详情。图中打开的是android4.4.2的API
勾选Sources for Android SDK,并点击install 1 package。
接着出现这个页面,点击Accept License,点击install,然后开始安装,稍等片刻后,安装成功。
安装成功后,当你想查看某个类或方法的实现细节,只需要按住ctrl键,将鼠标指向该类或方法,鼠标由箭头变成手指后,点击即可进入该类的源代码。如下图是activity类的源码。
Android-Fragment源码分析
Fragment是Android系统为了提高应用性能和降低资源消耗而引入的一种更轻量级的组件,它允许开发者在同一个Activity中加载多个UI组件,实现页面的切换与回退。Fragment可以看作是Activity的一个子部分,它有自己的生命周期和内容视图。
在实际应用中,Fragment可以用于构建动态、可复用的UI组件,例如聊天应用中,左右两边的布局(联系人列表和聊天框)可以分别通过Fragment来实现,通过动态地更换Fragment,达到页面的切换效果,而无需整个页面的刷新或重新加载。
在实现上,v4.Fragment与app.Fragment主要区别在于兼容性。app.Fragment主要面向Android 3.0及以上版本,而v4.Fragment(即支持包Fragment)则旨在提供向下兼容性,支持Android 1.6及更高版本。使用v4.Fragment时,需要继承FragmentActivity并使用getSupportFragmentManager()方法获取FragmentManager对象。尽管从API层面看,两者差异不大,但官方倾向于推荐使用v4.Fragment,以确保更好的兼容性和性能优化。
下面的示例展示了如何使用v4.Fragment实现页面的加载与切换。通过创建Fragment和FragmentActivity,我们可以加载特定的Fragment,并在不同Fragment间进行切换。
在FragmentDemo的布局文件中,定义了Fragment容器。
在Fragment代码中,定义了具体的业务逻辑和视图渲染,如初始化界面数据、响应用户事件等。
在Activity代码中,通过FragmentManager的beginTransaction方法,加载指定的Fragment实例,并在需要时切换到不同Fragment,实现页面的动态更新。
从官方的建议来看,v4.Fragment已经成为推荐的使用方式,因为它在兼容性、性能和功能方面都更优于app.Fragment。随着Android系统的迭代,使用v4.Fragment能确保应用在不同版本的Android设备上均能获得良好的运行效果。
在Fragment的生命周期管理中,Fragment与Activity的生命周期紧密关联。通过FragmentManager的操作,如commit、replace等,可以将Fragment加入到Activity的堆栈中,实现页面的加载与切换。当用户需要返回时,系统会自动将当前Fragment从堆栈中移除,从而实现页面的回退。
深入Fragment源码分析,我们可以了解其如何在底层实现这些功能。Fragment的初始化、加载、切换等过程涉及到多个关键类和方法,如FragmentManager、FragmentTransaction、BackStackRecord等。通过这些组件的协作,Fragment能够实现与Activity的生命周期同步,确保用户界面的流畅性和高效性。
在实际开发中,使用Fragment可以显著提高应用的响应速度和用户体验。通过动态加载和切换不同的Fragment,开发者可以构建出更加灵活、高效的应用架构,同时减少资源的消耗,提高应用的性能。
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çæµç¨ç±»ä¼¼ã