前言
在Android中,有些应用没有通过Service或者Broadcast等启动他,但Application还是被启动了。
经过查阅资料和看代码,发现android:persistent="true"的妙用之处。
实现Application,然后AndroidManifest.xml中注册Application,并在其属下中添加android:persistent="true",如下:
<application android:allowBackup="true" android:name="com.water.app.WaterApp" android:icon="@mipmap/ic_launcher" android:persistent="true" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> ...... </application>
下面我们来简单的分析一下是不是所有应用设置android:persistent="true"都是有效的。
正文
android:persistent="true"对任何应用有效么?
- ActivityManagerService.java
目录地址:\frameworks\base\services\core\java\com\android\server\am\ActivityManagerService.java
public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) { ..... startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE); ..... }
void startPersistentApps(int matchFlags) { if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return; synchronized (this) { try { final List<ApplicationInfo> apps = AppGlobals.getPackageManager() .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList(); for (ApplicationInfo app : apps) { if (!"android".equals(app.packageName)) { addAppLocked(app, null, false, null /* ABI override */); } } } catch (RemoteException ex) { } } }
- PackageManagerService.java
目录地址:frameworks\base\services\core\java\com\android\server\pm\PackageManagerService.java
@Override public @NonNull ParceledListSlice<ApplicationInfo> getPersistentApplications(int flags) { if (getInstantAppPackageName(Binder.getCallingUid()) != null) { return ParceledListSlice.emptyList(); } return new ParceledListSlice<>(getPersistentApplicationsInternal(flags)); } private @NonNull List<ApplicationInfo> getPersistentApplicationsInternal(int flags) { final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>(); // reader synchronized (mPackages) { final Iterator<PackageParser.Package> i = mPackages.values().iterator(); final int userId = UserHandle.getCallingUserId(); while (i.hasNext()) { final PackageParser.Package p = i.next(); if (p.applicationInfo == null) continue; final boolean matchesUnaware = ((flags & MATCH_DIRECT_BOOT_UNAWARE) != 0) && !p.applicationInfo.isDirectBootAware(); final boolean matchesAware = ((flags & MATCH_DIRECT_BOOT_AWARE) != 0) && p.applicationInfo.isDirectBootAware(); if ((p.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0 && (!mSafeMode || isSystemApp(p)) && (matchesUnaware || matchesAware)) { PackageSetting ps = mSettings.mPackages.get(p.packageName); if (ps != null) { ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags, ps.readUserState(userId), userId); if (ai != null) { finalList.add(ai); } } } } } return finalList; }
在PackageManagerService.java解析apk时会把带有ApplicationInfo.FLAG_PERSISTENT的apk解析出来。
上面也有是否是系统应用和安全模式判断,如下代码:
if ((p.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0 && (!mSafeMode || isSystemApp(p)) && (matchesUnaware || matchesAware)) { PackageSetting ps = mSettings.mPackages.get(p.packageName); if (ps != null) { ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags, ps.readUserState(userId), userId); if (ai != null) { finalList.add(ai); } } }
也就是非系统应用需要再[非安全模式]下才可以是启动,如果是[安全模式]且[非系统应用],即使你设置了persistent属性也是无法被启动Application、
总结
需要android:persistent="true"有效,除了设置了这个属性,还需要满足下面中的一个。
- 非安全模式
- 系统应用
参考文章
历史上的今天
暂无评论...
随机推荐
Android加载动画常用做法简介
前言Android开发中常用到加载动画,因此今天有空记录一下使用方法和性能对比,方便自己查阅。正文效果就是一直旋转,下面是用到的部分加载图片(忘记保留来源地址了,只知道来自简书面,抱歉)隐藏内容!付费阅读后才能查看!¥2 ¥3多个隐藏块只需支付一次付费阅读参考文章
wordpress设置固定链接后不能访问
前言我用的是nginx服务器,用的是WordPress博客系统。在wordpress后台固定链接后,导致文章无法访问。记录一下,方便自己查阅。正文找到nginx.conf#每个人的可能不一样/etc/nginx/nginx.conf新增配置,在server{}中server{ ...
Android磁盘之U盘卸载
前言之前介绍了U盘的挂载,那当然不能少了U盘的卸载。这里大概的记录一下,方便自己查阅。Android P这里很多都是网上的,我就走走流程。正文VolumeManager.cpphandleBlockEvent()void VolumeManager::handleBlockEve...
MediaProvider源码分析
前言MediaProvider继承自ContentProvider,是Android用于存储图片、音频、视频和文档等多媒体信息,提供给其他需要的应用使用。今天就对MediaProvider应用代码进行一定学习。参考网上大佬文章,记录一下过程。这里是用了Android P源码分析正文M...
Ubuntu16.0.4安装搜狗输入法笔记
1、下载搜狗输入法安装包下载地址为:http://pinyin.sogou.com/linux/ ,如下图,要选择与自己系统位数一致的安装包。、2、使用命令安装搜狗输入法sudo dpkg -i sogoupinyin.deb3、设置搜狗输入为默认点击右上角的System setting...
C语言之链接属性
前言对于C语言的链接属性,比较模糊,因此今天回归一下课本上的知识,并记录一下,方便自己回顾。正文链接属性链接属性用于认定不同文件的标识符(比如变量名、函数名)是否是同一个实体。通俗地说,就是在两个不同文件中的变量、函数声明是否指向同一个实体。比如:a、b文件同时声明了变量c,链接属性就指...