`
OliveExcel
  • 浏览: 70553 次
文章分类
社区版块
存档分类
最新评论

一个获取Android应用(或Activity)启动时间的工具

阅读更多

需求: 要求得到某个Activity的启动时间

 

实现:

1. adb shell下面存在am命令, 使用start -W -n参数, 即可获取Activity启动时间的信息;

2. 上述Activity的启动信息中, 包含了本次启动时间.

 

================================= 需求变更的分割线 =================================

 

需求: 要求得到某个Activity的启动时间, 需要将此功能集成到APK

 

实现:

1. 通过Process process = Runtime.getRuntime().exec(cmd)执行命令;

2. 通过上述process.getInputStream()获取命令执行结果;

3. 解析命令执行结果, 得到Activity启动时间.

 

但是, 上面这个方案看着不是很爽, 想找个替代方案.

百度了一下, 豁然开朗: am命令是用java实现的, cat一下system/bin/am, 就可以看到它里面实际上封装了system/framework/am.jar. 然后在源码中找到了am.jar的工程(此处存在一堆找代码的过程, 最后再扯).

 

来读一下代码:

1. 既然是java工程, 那势必要先找到public static void main();

2. 发现里面就一句话:

 

(new Am()).run(args);
3. 我X, 过分, 这个run()方法还是在父类BaseCommand里的. 没错, 这一步我就是写来吐槽找代码麻烦的!

 

4. 父类的run()方法的关键代码:

 

public void run(String[] args) {
    if (args.length < 1) {
        onShowUsage(System.out);
        return;
    }
    ...
    onRun();
    ...
}
即校验完参数个数, 就开始入正题了, 正题跑的是Am.onRun();

 

5. 接下来就好办了, 找start参数的处理逻辑: 由于我关心的是最后输出内容中的"ThisTime", 因此找到它是怎样赋值, 就算是定位到数据源. 于是有了方案如下:

 

实现二:

1. Am.java中, 通过IActivityManager.startActivityAndWait()方法, 启动目标Activity, 并从方法返回值中获取Activity启动时间等信息. 由于IActivityManager及其方法是hide的, 所以需要通过反射获取;

2. 获取IActivityManager实例:

 

Class activityManagerNativeClazz = Class.forName("android.app.ActivityManagerNative");
Method getIActivityManager = activityManagerNativeClazz.getDeclaredMethod("getDefault", new Class[] {});
Object iActivityManagerInstance = getIActivityManager.invoke(activityManagerNativeClazz, null);
2. 从IActivityManager中找到startActivityAndWait()这个方法(没有通过方法 + 参数类型来拿, 是因为懒, 这个方法有好多参数... 并且同名的方法就这一个, 不怕拿错):

 

Method startActivityAndWait = null;
for (Method method : iActivityManagerInstance.getClass().getDeclaredMethods()) {
    if ("startActivityAndWait".equals(method.getName())) {
        startActivityAndWait = method;
        break;
    }
}

3. 构造启动Activity的Intent. Am.java中, 通过目标包名 + 目标Activity类名构造Intent, 可以照搬为如下代码:

 

Intent intent = new Intent();
intent.setComponent(ComponentName.unflattenFromString(packageName + "/" + activityName));
4. invoke方法, 启动目标Activity:
startActivityAndWait.invoke(iActivityManagerInstance, params);
5. 上一步执行的返回值是android.app.IActivityManager$WaitResult类型的, 由于它也属于hide API, 所以获取到实例后, 再次通过反射拿到WaitResult.thisTime的值, 作为Activity启动时间.

 

 

================================= 与方案无关的分割线 =================================

 

补上找代码的过程:

1. 如果am.jar不是第三方的库(应该不会是, 因为这个jar包处理的是Android的东西), 那么就应该由系统中的java文件编译而来. 那么就一定会有编译中间件. 经查找中间件, 发现其中包含有am_intermediates, 那么可以确定一个信息, am.jar的module name就是am;

2. 通过对mk文件进行检索, 关键字: LOCAL_MODULE := am;

3. 定位到工程源码位于frameworks/base/cmds/am;

4. 这是个java工程, 并且整个工程只有一个源码文件...

5. Am.java的父类BaseCommand, 通过文件名检索, 可以找到位于frameworks/base/core/java/com/android/internal/os路径下.

分享到:
评论
发表评论

文章已被作者锁定,不允许评论。

相关推荐

    androidkit(android应用开发工具包)

    androidkit是一个android应用开发工具包,包含SQLiteOpenHelper的简单实现类、获取指定URL中返回的内容的String对象、View控件的截图、获取 本程序的图标、名字、版本、包名等信息、再按一次退出、抽象类,继承并...

    Android APP 小工具测试“利器”

    Android 测试小工具基于Maven的Java Swing GUI桌面应用开发并集成adb命令完成应用程序信息快速查看,工具的主要用途用于快速获取安卓设备当前正在运行的最顶层APP的相关信息,如:PackName、PackBit、Launchable_...

    谈谈Android里的Context的使用

    第3步:新建一个View命名为MainView.java就是我们Activity现实的View.代码如下: package com.tutor.application; import android.app.Activity; import android.content.Context; import android.util....

    通用Android工具库Common4Android.zip

    Common4Android是一个通用Android工具库,包含网络库、线程管理器、常用Util工具、热修复,它拥有良好的架构,低耦合、高内聚,使用起来非常轻松。 -基类 ClassName Description ...

    新版Android开发教程.rar

    Android 是一个专门针对移动设备的软件集,它包括一个操作系统,中间件和一些重要的应用程序。 Beta 版 的 Android SDK 提供了在 Android 平台上使用 JaVa 语言进行 Android 应用开发必须的工具和 API 接口。 特性 ...

    《Android系统源代码情景分析》

    1.5 开发第一个Android应用程序 1.6 单独编译和打包Android应用程序模块 1.6.1 导入单独编译模块的mmm命令 1.6.2 单独编译Android应用程序模块 1.6.3 重新打包Android系统镜像文件 第2章 硬件抽象层 ...

    Android系统源代码情景分析-罗升阳-源码

    1.5 开发第一个Android应用程序 1.6 单独编译和打包Android应用程序模块 1.6.1 导入单独编译模块的mmm命令 1.6.2 单独编译Android应用程序模块 1.6.3 重新打包Android系统镜像文件 第2章 硬件抽象层 2.1 ...

    android开发入门与实战(下)

    9.1.2 用Intent启动一个新的Activity 9.1.3 Intent详细讲解 9.1.4 Android解析Intent实现 9.2 用广播告诉你——利用Intent来广播(BroadCast)事件 9.2.1 实现Android中的广播事件 9.2.2 BroadCastReceiver介绍 9.3 ...

    android开发入门与实战(上)

    9.1.2 用Intent启动一个新的Activity 9.1.3 Intent详细讲解 9.1.4 Android解析Intent实现 9.2 用广播告诉你——利用Intent来广播(BroadCast)事件 9.2.1 实现Android中的广播事件 9.2.2 BroadCastReceiver介绍 9.3 ...

    疯狂Android讲义源码

     1.4 开始第一个Android应用 20  1.4.1 使用Eclipse开发第一个  Android应用 20  1.4.2 通过ADT运行Android应用 23  1.5 Android应用结构分析 24  1.5.1 创建一个Android应用 24  1.5.2 自动生成的R.java 26 ...

    《Google Android开发入门与实战》.pdf

    9.1.2 用intent启动一个新的activity 174 9.1.3 intent 详细讲解 177 9.1.4 android解析intent实现 179 9.2 用广播告诉你——利用intent来广播(broadcast)事件 180 9.2.1 实现android中的广播事件 180...

    Google.Android开发入门与实战

     由于Android平台被推出的时间才一年左右,了解Android平台软件开发技术的程序员还不多,如何迅速地推广和普及Android平台软件开发技术,让越来越多的人参与到Android应用的开发中,是整个产业链都在关注的一个话题...

    android开发秘籍

    2.3.2 秘诀7:通过事件启动另外一个activity 29 2.3.3 秘诀8:将语音转换成文本并启动activity 显示结果 32 2.3.4 秘诀9:实现选择列表 34 2.3.5 秘诀10:使用隐式intent 创建activity 35 2.3.6 秘诀11:在activity...

    工程硕士学位论文 基于Android+HTML5的移动Web项目高效开发探究

    Activity Activity是一个应用程序组件,提供一个屏幕,用户可以用来交互为了完成某项任务,是一个负责与用户交互的组件 SSH 为 Struts+Spring+Hibernate的一个集成框架,是目前较流行的一种Web应用程序开源框架。...

    (完整)Android手机天气预报项目报告.doc

    第2章 项目设计 2.1 项目总体设计 本软件是一个App Widget应用程序,启动程序后可以进行城市、更新频率的设置,可以通过图片和文字显 示当前和未来的天气状况,包括温度、湿度、风向和雨雪情况等.这些天气数据是...

    Android手机天气预报项目报告.docx

    第2章 项目设计 2.1 项目总体设计 本软件是一个App Widget应用程序,启动程序后可以进行城市、更新频率的设置,可以通过图片和文字显示当前和未来的天气状况,包括温度、湿度、风向和雨雪情况等。这些天气数据是...

    疯狂Android讲义.part1

    1.4 开始第一个Android应用 20 1.4.1 使用Eclipse开发第一个 Android应用 20 1.4.2 通过ADT运行Android应用 23 1.5 Android应用结构分析 24 1.5.1 创建一个Android应用 24 1.5.2 自动生成的R.java 26 1.5.3 res目录...

    Google Android开发入门与实战的代码

    9.1.2 用Intent启动一个新的Activity 174 9.1.3 Intent 详细讲解 177 9.1.4 Android解析Intent实现 179 9.2 用广播告诉你——利用Intent来广播(BroadCast)事件 180 9.2.1 实现Android中的广播事件 180...

    Android开发艺术探索.任玉刚(带详细书签).pdf

    本书是一本Android进阶类书籍,采用理论、源码和实践相结合的方式来阐述高水准的Android应用开发要点。本书从三个方面来组织内容。第一,介绍Android开发者不容易掌握的一些知识点;第二,结合Android源代码和应用层...

Global site tag (gtag.js) - Google Analytics