Android 启动 应用程序详情AppInfo(AppDetail) -源码分析

article/2025/11/11 17:24:08

在Launcher (桌面)上,长按应用图标然后点击 右上角的 应用详情 按钮,
将会进入 该 应用的详情 界面。
这个过程将会涉及 Client (Launcher App) -> App API(LauncherApps ) -> Framework API(LauncherAppsService)
下面将以 LauncherApps -> LauncherAppsService 深入Framework 分析,然后再看在 客服端的调用

1. 客户端接口 LauncherApps.startAppDetailsActivity

frameworks/base/core/java/android/content/pm/LauncherApps.java

@SystemService(Context.LAUNCHER_APPS_SERVICE)
public class LauncherApps {/** @hide */public LauncherApps(Context context, ILauncherApps service) {mContext = context;mService = service;mPm = context.getPackageManager();mUserManager = context.getSystemService(UserManager.class);}/*** Starts the settings activity to show the application details for a* package in the specified profile.** @param component The ComponentName of the package to launch settings for.* @param user The UserHandle of the profile* @param sourceBounds The Rect containing the source bounds of the clicked icon* @param opts Options to pass to startActivity*/public void startAppDetailsActivity(ComponentName component, UserHandle user,Rect sourceBounds, Bundle opts) {logErrorForInvalidProfileAccess(user);try {mService.showAppDetailsAsUser(mContext.getIApplicationThread(),mContext.getPackageName(), mContext.getAttributionTag(),component, sourceBounds, opts, user);} catch (RemoteException re) {throw re.rethrowFromSystemServer();}}

客户端 可以通过 context.getSystemService(Context.LAUNCHER_APPS_SERVICE)
或者 context.getSystemService(LauncherApps.class)
获取到LauncherApps 实例对象.

2. AIDL 接口 ILauncherApps.showAppDetailsAsUser

上面的代码可以看出,实际上是通过 AIDL 接口进行调用方法 showAppDetailsAsUser,即:
frameworks/base/core/java/android/content/pm/ILauncherApps.aidl

interface ILauncherApps {....void showAppDetailsAsUser(in IApplicationThread caller, String callingPackage,String callingFeatureId, in ComponentName component, in Rect sourceBounds,in Bundle opts, in UserHandle user);    
}

3. system_server 实现 LauncherAppsService.showAppDetailsAsUser

showAppDetailsAsUser 最终的实现是在 system_server 进程里的
frameworks/base/services/core/java/com/android/server/pm/LauncherAppsService.java

        @Overridepublic void showAppDetailsAsUser(IApplicationThread caller,String callingPackage, String callingFeatureId, ComponentName component,Rect sourceBounds, Bundle opts, UserHandle user) throws RemoteException {if (!canAccessProfile(user.getIdentifier(), "Cannot show app details")) {return;}final Intent intent;final long ident = Binder.clearCallingIdentity();try {String packageName = component.getPackageName();int uId = -1;try {uId = mContext.getPackageManager().getApplicationInfo(packageName, PackageManager.MATCH_ANY_USER).uid;} catch (PackageManager.NameNotFoundException e) {Log.d(TAG, "package not found: " + e);}intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS,Uri.fromParts("package", packageName, null));intent.putExtra("uId", uId);intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);intent.setSourceBounds(sourceBounds);} finally {Binder.restoreCallingIdentity(ident);}mActivityTaskManagerInternal.startActivityAsUser(caller, callingPackage,callingFeatureId, intent, /* resultTo= */ null, Intent.FLAG_ACTIVITY_NEW_TASK,opts, user.getIdentifier());}

可以看出,最后调用的其实是 ATMS 的 startActivityAsUser 方法

4. PackageManagerHelper. startDetailsActivityForInfo 客户端封装接口

packages/apps/Launcher3/src/com/android/launcher3/util/PackageManagerHelper.java

    /*** Starts the details activity for {@code info}*/public void startDetailsActivityForInfo(ItemInfo info, Rect sourceBounds, Bundle opts) {if (info instanceof ItemInfoWithIcon&& (((ItemInfoWithIcon) info).runtimeStatusFlags& ItemInfoWithIcon.FLAG_INSTALL_SESSION_ACTIVE) != 0) {ItemInfoWithIcon appInfo = (ItemInfoWithIcon) info;mContext.startActivity(new PackageManagerHelper(mContext).getMarketIntent(appInfo.getTargetComponent().getPackageName()));return;}ComponentName componentName = null;if (info instanceof AppInfo) {componentName = ((AppInfo) info).componentName;} else if (info instanceof WorkspaceItemInfo) {componentName = info.getTargetComponent();} else if (info instanceof PendingAddItemInfo) {componentName = ((PendingAddItemInfo) info).componentName;} else if (info instanceof LauncherAppWidgetInfo) {componentName = ((LauncherAppWidgetInfo) info).providerName;}if (componentName != null) {try {mLauncherApps.startAppDetailsActivity(componentName, info.user, sourceBounds, opts);} catch (SecurityException | ActivityNotFoundException e) {Toast.makeText(mContext, R.string.activity_not_found, Toast.LENGTH_SHORT).show();Log.e(TAG, "Unable to launch settings", e);}}}

可以看出,最终调用的就是 LauncherApps.startAppDetailsActivity,
只不过这里对 具体的 组件名称 进行了解析

5. 应用详情 进入点 AppInfo.onClick

其中,AppInfo 是 SystemShortcut 的子类以及内部类。
packages/apps/Launcher3/src/com/android/launcher3/popup/SystemShortcut.java

/*** Represents a system shortcut for a given app. The shortcut should have a label and icon, and an* onClickListener that depends on the item that the shortcut services.** Example system shortcuts, defined as inner classes, include Widgets and AppInfo.* @param <T>*/
public abstract class SystemShortcut<T extends Context & ActivityContext> extends ItemInfoimplements View.OnClickListener {...public static class AppInfo<T extends Context & ActivityContext> extends SystemShortcut<T> {@Nullableprivate SplitAccessibilityInfo mSplitA11yInfo;public AppInfo(T target, ItemInfo itemInfo, View originalView) {super(R.drawable.ic_info_no_shadow, R.string.app_info_drop_target_label, target,itemInfo, originalView);}@Overridepublic void onClick(View view) {dismissTaskMenuView(mTarget);Rect sourceBounds = Utilities.getViewBounds(view);new PackageManagerHelper(mTarget).startDetailsActivityForInfo(mItemInfo, sourceBounds, ActivityOptions.makeBasic().toBundle());mTarget.getStatsLogManager().logger().withItemInfo(mItemInfo).log(LAUNCHER_SYSTEM_SHORTCUT_APP_INFO_TAP);}       
}

可以看到,这里 onClick 函数调用了上面的 PackageManagerHelper.startDetailsActivityForInfo。
当然,注释里也说明了,这个 AppInfo 只是一个例子,Launcher App也可以自定义。

最后

如果想要成为架构师或想突破20~30K薪资范畴,那就不要局限在编码,业务,要会选型、扩展,提升编程思维。此外,良好的职业规划也很重要,学习的习惯很重要,但是最重要的还是要能持之以恒,任何不能坚持落实的计划都是空谈。

如果你没有方向,这里给大家分享一套由阿里高级架构师编写的《Android八大模块进阶笔记》,帮大家将杂乱、零散、碎片化的知识进行体系化的整理,让大家系统而高效地掌握Android开发的各个知识点。
img
相对于我们平时看的碎片化内容,这份笔记的知识点更系统化,更容易理解和记忆,是严格按照知识体系编排的。

欢迎大家一键三连支持,若需要文中资料,直接扫描文末CSDN官方认证微信卡片免费领取↓↓↓

PS:群里还设有ChatGPT机器人,可以解答大家在工作上或者是技术上的问题
图片


http://chatgpt.dhexx.cn/article/5kNKkbLn.shtml

相关文章

AppInfoPro 获取手机应用信息

AppInfoKtx Github Android - 获取手机安装的应用信息&#xff08;用户应用、系统应用&#xff09;、手机信息、屏幕信息&#xff0c;并且支持扫描本地符合指定要求&#xff08;后缀&#xff09;的应用&#xff0c;并且获取该apk信息&#xff0c;支持导出应用信息&#xff08;…

关于Vista的AppInfo服务被禁的问题

昨天参考了这个文章对vista服务进行了大张旗鼓的阉割,冒险地把大部分服务都给卡擦了(不想转贴了,这个文章本身也是转贴的) http://blog.tom.com/pslwap/article/1411.html 然后就出现了郁闷的事情: 重新启动后任何需要提升权限来操作的程序都无法启动,提示"无法启动服务…

Android8.1根据app名字调用显示app的属性页(App info)

https://actionwind.wordpress.com/2022/04/14/android8-1%e6%a0%b9%e6%8d%aeapp%e5%90%8d%e5%ad%97%e8%b0%83%e7%94%a8%e6%98%be%e7%a4%baapp%e7%9a%84%e5%b1%9e%e6%80%a7%e9%a1%b5%ef%bc%88app-info%ef%bc%89/ 如果要让手机显示出app的属性页&#xff1a; 代码如下&#xff1…

vue项目打包部署注意点 + 宝塔面板几步部署项目

1.vue项目打包 1.1 终端运行打包命令 在编辑器的终端运行vue项目打包命令 yarn run build打包成功如下&#xff1a; 这时我们可以看到项目目录多出来一个dist文件夹&#xff0c;记住它&#xff0c;后面部署就靠它了。 1.2 修改配置 就我个人部署经历(宝塔面板快速部署)来…

vue项目打包部署到tomcat服务器

总结&#xff1a; 修改vue项目相关配置&#xff0c;cmd进入到vue项目文件夹中&#xff0c;执行npm run bulid命令&#xff0c;将生成的dist文件夹下的内容&#xff0c;存放到Tomcat中的webapps新建文件夹下&#xff0c;运行Tomcat服务器&#xff0c;通过 IP地址:端口/新建文件…

vue项目打包部署-手把手教程

vue项目打包部署 1.购买服务器 可选阿里云/腾讯云/华为云 等等… 购买时选择镜像,我们这里以CentOS为例 2.配置服务器 2.1 安装FinalShell ​ 需要本地使用一些软件来操作服务器,例如:FinalShell / Xshell … ​ 我这里使用的是FinalShell,安装好以后,打开软件与建立链接…

Java和Vue项目打包并进行服务器部署

两周前我刚刚入职实习的时候&#xff0c;后端的几个同事看到我需要学习如何把项目进行部署&#xff0c;都围过来教我怎么部署&#xff0c;我感觉学习到了很多&#xff0c;因此&#xff0c;记录一下学习的笔记。 当然了&#xff0c;这些部署是建立在已经配置好tomcat&#xff08…

手把手教你如何把vue项目打包后部署到服务器(小白教程)

一.需要用到的工具 vscode 下载链接&#xff1a;Visual Studio Code - Code Editing. Redefined FinalShell 下载链接&#xff1a;FinalShell官网 二.打包步骤 1.vscode打开你的vue项目-- >点终端 -- >输入npm run build 按回车进行打包&#xff1b; 2.打包成功 , 生…

Vue项目的打包\部署\优化

Vue项目的打包\部署\优化 如果有帮助到你 麻烦点个赞或者 收藏 关注 哟 以后会经常发布一些干货文章 我只是一个前端小菜鸟&#xff0c;大佬勿喷! 一、nginx 开启 gzip 理论上&#xff0c;nginx 开启 gzip 成功后&#xff0c;文件大小应该小很多&#xff0c;如果你发现你的…

vue项目打包步骤及运行打包项目

** 1.项目打包 ** 终端运行命令 npm run build 打包成功的标志与项目的改变&#xff0c;如下图&#xff1a; 点击index.html&#xff0c;通过浏览器运行&#xff0c;出现以下报错&#xff0c;如图&#xff1a; 解决&#xff1a; 修改 1、查看package.js文件的scripts命令…

Vue项目部署,打包发布上线

参考vuecli官方文档 一、构建打包 在发布上线之前&#xff0c;我们需要执行构建打包&#xff0c;将 .less、.vue、.js 等相关资源进行编译打包&#xff0c;转换成浏览器可以直接识别运行的普通 css、js、html。 # yarn run build 或者 yarn build npm run buildVueCLI 会把打…

Vue项目打包部署到服务器(Linux)

一、打包&#xff08;build&#xff09; npm run build / yarn build 打包完成后项目路径会多出一个dist文件夹 到这里本地的打包完成了 然后到服务器 二、服务器配置&#xff08;nginx&#xff09; **注&#xff1a;如果已经有nginx环境了的话直接到第6小步** 1、查看gcc版本…

vue项目打包部署在windows或linux服务器上

最近写了一个前后端分离的项目&#xff0c;前端用的是vue&#xff0c;因此记录一下将该项目部署到服务器的整个过程。 1.首先&#xff0c;在控制台输入npm run build命令&#xff08;或者npm run build:prod)。该命令用于将前端vue打包。打包后的文件是dist文件夹。&#xff0…

Spring Boot+Vue项目打包部署

在前后端分离的项目中&#xff0c;最后前后端项目开发完毕都需要进行打包部署发布到服务器上面运行&#xff0c;所以需要对前端开发的项目进行打包&#xff0c;然后将打包后的文件放在spring boot项目中的resource/static目录下面 前端项目 点击edit configuration进入run/deb…

vue项目打包部署到腾讯云全过程

文章目录 1.打包本地vue项目2.购买云服务器3.使用xshell4.在xshell里安装宝塔5.宝塔操作6.成功访问 关于前端部署研究了挺久的&#xff0c;一开始毫无头绪也走了很多弯路&#xff0c;看了许多视频和文档之后&#xff0c;才慢慢有了了解&#xff0c;成功访问之后特别开心&#x…

Vue项目webpack打包部署到服务器

Vue项目webpack打包部署到服务器 这篇博文主要说的就是我今天遇到的问题&#xff0c;而且在经过我的询问&#xff0c;好多人在打包部署的时候都遇到了一些问题&#xff0c;下面就来说下&#xff0c;如何将Vue项目放置在服务器上&#xff0c;这里以Tomcat为例。 必须要配置的就…

【前端部署】vue项目打包并部署到Linux服务器

文章目录 一、打包vue前端项目二、安装nginx1.下载及安装2.启动程序3.其他命令 三、利用WinSCP传输文件四、配置nginx1.修改服务器端口2.修改dist存放路径3.完整配置文件 五、进入界面和项目更新1.进入界面2.项目更新 总结 一、打包vue前端项目 在vs code中打开vue前端项目文件…

【转】怎样运行 Vue 打包后的项目

1. 一般打包完成后会在项目根目录生成一个 dist 文件夹&#xff0c;此时&#xff0c;我们在项目根目录新建一个 js 文件&#xff08;我以 server.js 为例&#xff09; server.js 中代码如下&#xff1a; const express require(express) const app express() const port 808…

vue项目打包步骤

vue项目打包 一、终端运行命令 npm run build 二、打包成功的标志与项目的改变&#xff0c;如下图&#xff1a; 3、点击index.html&#xff0c;通过浏览器运行&#xff0c;出现以下报错&#xff0c;如图&#xff1a; 四、那么应该如何修改呢&#xff1f; 具体步骤如下&#x…

Vue项目如何打包并且发布

如何将Vue项目打包并发布&#xff1f;我这边是测试发布到本地&#xff0c;不过步骤是一样的&#xff0c;步骤如下&#xff1a; 1、安装部署Nginx服务器。&#xff08;类似Tomcat服务器&#xff09; 说明&#xff1a;Nginx (engine x) 是一个高性能的HTTP和反向代理服务器&…