文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Android中persistent属性用法详解

2022-06-06 08:14

关注

本文实例讲述了Android中persistent属性用法。分享给大家供大家参考,具体如下:

前段时间在研究telephony时,一直没有在framework下发现对telephony的初始化(PhoneFactory.Java中的makeDefaultPhones函数)的调用。结果全局搜索之后发现在application PhoneApp(packages/apps/Phone)中调用了。但是application PhoneApp既没有被Broadcast唤醒,也没有被其他service调用,那么是Android是通过什么方式来启动PhoneApp,所以就发现了属性android:persistent。

在AndroidManifest.xml定义中,application有这么一个属性android:persistent,根据字面意思来理解就是说该应用是可持久的,也即是常驻的应用。其实就是这么个理解,被android:persistent修饰的应用会在系统启动之后被AM启动。

AM首先去PM(PackageManagerService)中去查找设置了Android:persistent的应用


public void systemReady(final Runnable goingCallback) {
  if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
    try {
      List apps = AppGlobals.getPackageManager().
        getPersistentApplications(STOCK_PM_FLAGS);
      if (apps != null) {
        int N = apps.size();
        int i;
        for (i=0; i<N; i++) {
          ApplicationInfo info
            = (ApplicationInfo)apps.get(i);
          if (info != null &&
              !info.packageName.equals("Android")) {
            addAppLocked(info);
          }
        }
      }
    } catch (RemoteException ex) {
      // pm is in same process, this will never happen.
    }
  }
}

假如该被Android:persistent修饰的应用此时并未运行的话,那么AM将调用startProcessLocked启动该app,关于startProcessLocked不再描述,另外一篇文章《How to start a new process for Android?》中做了详细的介绍(这篇英文文档小编就不翻译了,感兴趣的朋友可以搜到看一看)。

app的启动过程就是启动app所在的package对应的进程。


final ProcessRecord addAppLocked(ApplicationInfo info) {
    ProcessRecord app = getProcessRecordLocked(info.processName, info.uid);
    if (app == null) {
      app = newProcessRecordLocked(null, info, null);
      mProcessNames.put(info.processName, info.uid, app);
      updateLruProcessLocked(app, true, true);
    }
    if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
        == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
      app.persistent = true;
      app.maxAdj = CORE_SERVER_ADJ;
    }
    if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
      mPersistentStartingProcesses.add(app);
      startProcessLocked(app, "added application", app.processName);
    }
    return app;
}

面介绍app所在的package对应的进程启动完成之后,app是如何被create的。

从文章《How to start a new process for Android?》中可知,zygote在创建新的进程均会启动它的mainThread android.app.ActivityThread,因此我们从ActivityThread的main函数中接着分析app的create过程。

在main中有下面这个操作


thread.attach(false);

在attach过程中,ActivityThread会将对应的application attach到AM中去,交与AM去管理。这里需要注意一个变量


final ApplicationThread mAppThread = new ApplicationThread();

mAppThread是一个ApplicationThread对象,mAppThread可以看作是当前进程主线程的核心,它负责处理本进程与其他进程(主要是AM)之间的通信,同时通过attachApplication将mAppThread的代理Binder传递给AM。


private final void attach(boolean system) {
    sThreadLocal.set(this);
    mSystemThread = system;
    if (!system) {
      ViewRoot.addFirstDrawHandler(new Runnable() {
        public void run() {
          ensureJitEnabled();
        }
      });
      Android.ddm.DdmHandleAppName.setAppName("<pre-initialized>");
      RuntimeInit.setApplicationObject(mAppThread.asBinder());
      IActivityManager mgr = ActivityManagerNative.getDefault();
      try {
        mgr.attachApplication(mAppThread);
      } catch (RemoteException ex) {
      }
    }
}

上面的attach代码中,我们顺着IPC调用AM的attachApplication过程再往下看。
在该过程中,AM调用到了IPC通信调用mAppThread的bindApplication;


private final boolean attachApplicationLocked(IApplicationThread thread,
  int pid) {
  thread.bindApplication(processName, app.instrumentationInfo != null
      ? app.instrumentationInfo : app.info, providers,
      app.instrumentationClass, app.instrumentationProfileFile,
      app.instrumentationArguments, app.instrumentationWatcher, testMode,
      isRestrictedBackupMode || !normalMode,
      mConfiguration, getCommonServicesLocked());
  updateLruProcessLocked(app, false, true);
  app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
}

mAppThread的bindApplication再通过消息机制向ActivityThread自身维护的handler发送BIND_APPLICATION消息。下面看看ActivityThread自身维护的handler对消息BIND_APPLICATION的处理,最终会调用到handleBindApplication函数

你会发现在handleBindApplication函数中有这么一句


mInstrumentation.callApplicationOnCreate(app);

我们最终在绕了好大一圈之后,调用了app的onCreate函数来启动这个application。

PS:更多关于AndroidManifest.xml配置项及其功能可参考本站在线工具:

Android Manifest功能与权限描述大全:
http://tools.jb51.net/table/AndroidManifest

更多关于Android相关内容感兴趣的读者可查看本站专题:《Android数据库操作技巧总结》、《Android编程之activity操作技巧总结》、《Android文件操作技巧汇总》、《Android编程开发之SD卡操作方法汇总》、《Android开发入门与进阶教程》、《Android资源操作技巧汇总》、《Android视图View技巧总结》及《Android控件用法总结》

希望本文所述对大家Android程序设计有所帮助。

您可能感兴趣的文章:Android源码系列之深入理解ImageView的ScaleType属性Android EditText常用属性功能汇总Android中LinearLayout布局的常用属性总结图文讲解Android的ImageView类中的ScaleType属性设置详解Android自定义控件属性TypedArray以及attrsAndroid开发之使用ExifInterface获取拍照后的图片属性Android编程开发之EditText中inputType属性小结Android编程开发之TextView文字显示和修改方法(附TextView属性介绍)Android中的windowSoftInputMode属性详解浅析Android中的visibility属性android教程之intent的action属性使用示例(intent发短信)android ListView 一些重要属性详解


阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     801人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     348人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     311人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     432人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     220人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-移动开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯