技术点:
先后台将所有app关闭,然后打开一个app。我的app中首页是MainActivity。
Running activities (most recent first):
TaskRecord{4145f710 #270 A com.hongx.hxlsn01 U 0}
Run #2: ActivityRecord{4102f8d0 u0 com.hongx.hxlsn01/.MainActivity}
TaskRecord{4170c6d8 #2 A com.huawei.android.launcher U 0}
Run #1: ActivityRecord{4170a3f8 u0 com.huawei.android.launcher/.Launcher}
TaskRecord{41e3ffe8 #157 I com.android.settings/.Settings$UsbSettingsActivity U 0}
Run #0: ActivityRecord{4155e5c8 u0 com.android.settings/.UsbSettings}
mResumedActivity: ActivityRecord{4102f8d0 u0 com.hongx.hxlsn01/.MainActivity}
mFocusedActivity: ActivityRecord{4102f8d0 u0 com.hongx.hxlsn01/.MainActivity}
mLastPausedActivity: ActivityRecord{4170a3f8 u0 com.huawei.android.launcher/.Launcher}
Running activities 表示正在运行的activity。
mLastPausedActivity 表示已经暂停的activity 为Launcher。
再去按下home键,dumpsys activity activities 后查看当前的activity名
Running activities (most recent first):
TaskRecord{4170c6d8 #2 A com.huawei.android.launcher U 0}
Run #2: ActivityRecord{4170a3f8 u0 com.huawei.android.launcher/.Launcher}
TaskRecord{4145f710 #270 A com.hongx.hxlsn01 U 0}
Run #1: ActivityRecord{4102f8d0 u0 com.hongx.hxlsn01/.MainActivity}
TaskRecord{41e3ffe8 #157 I com.android.settings/.Settings$UsbSettingsActivity U 0}
Run #0: ActivityRecord{4155e5c8 u0 com.android.settings/.UsbSettings}
mResumedActivity: ActivityRecord{4170a3f8 u0 com.huawei.android.launcher/.Launcher}
mFocusedActivity: ActivityRecord{4170a3f8 u0 com.huawei.android.launcher/.Launcher}
mLastPausedActivity: ActivityRecord{4102f8d0 u0 com.hongx.hxlsn01/.MainActivity}
从输出中可以看出,正在运行的activity为Launcher,已暂停的activity变成了MainActivity。
Launcher 概述
系统启动的最后一步是启动一个应用程序用来显示系统中已经安装的应用程序,这个应用程序就叫作 Launcher。Launcher 在启动过程中会请求 PackageManagerService 返回系统中已经安装的应用程序的信息,并将这些信息封装成一个快捷图标列表显示在系统屏幕上,这样用户可以通过点击这些快捷图标来启动相应的应用程序。
E:\tools\android-src\android-6.0.1_r1\packages\apps\
Launcher2\src\com\android\launcher2\Launcher.java
当我们用手点击一个图标时,就到了这个类public final class Launcher extends Activity
执行onClick(View view)方法,会把这个应用的相关信息传入
先获取一个intent—>startActivitySafely(v, intent, tag)–》startActivity(v, intent, tag);–>startActivity(intent);
startActivity(intent)会开一个APP进程
ActivityThread.java做为入口 用attach开启app 再加载application和activity
thread.attach(false);—》mgr.attachApplication(mAppThread)会通过远端进程去
回调private void handleBindApplication(AppBindData data)
Application app = data.info.makeApplication(创建Application对象
mInstrumentation.callApplicationOnCreate(app);----》 app.onCreate();
res/values/styles.xml文件
白屏
再在功能清单中的单独activity下设置
QQ中的用法
- true
- @null
4.4版本以后Logcat 输入Displayed筛选系统日志 不过滤信息No Filters
4.4以前 adb shell am start -W com.lqr.wechat/com.lqr.wechat.activity.SplashActivity
adb shell am start -W com.lqr.wechat/com.lqr.wechat.activity.SplashActivity
Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.lqr.wechat/.activity.SplashActivity }
Status: ok
Activity: com.lqr.wechat/.activity.SplashActivity
ThisTime: 883
TotalTime: 883
WaitTime: 915
Complete
查看进程 adb shell ps
在输出中找到进程
u0_a533 25343 1275 4484104 190652 0 0 efg S com.lqr.wechat
u0_a533 25368 1275 4388180 97448 0 0 efg S com.lqr.wechat:core
u0_a533 25401 1275 4385168 93684 0 0 ebg S com.lqr.wechat:cosine
u0_a533 25436 1 4389532 41984 0 0 ebg S com.lqr.wechat:cosine
Am.java
AM路径\frameworks\base\cmds\am\src\com\android\commands\am
IActivityManager.WaitResult result = null;
int res;
final long startTime = SystemClock.uptimeMillis();
ActivityOptions options = null;
if (mStackId != INVALID_STACK_ID) {
options = ActivityOptions.makeBasic();
options.setLaunchStackId(mStackId);
}
if (mWaitOption) {
result = mAm.startActivityAndWait(null, null, intent, mimeType,
null, null, 0, mStartFlags, profilerInfo,
options != null ? options.toBundle() : null, mUserId);
res = result.result;
} else {
res = mAm.startActivityAsUser(null, null, intent, mimeType,
null, null, 0, mStartFlags, profilerInfo,
options != null ? options.toBundle() : null, mUserId);
}
final long endTime = SystemClock.uptimeMillis();
if (result == null) {
result = new IActivityManager.WaitResult();
result.who = intent.getComponent();
}
System.out.println("Status: " + (result.timeout ? "timeout" : "ok"));
if (result.who != null) {
System.out.println("Activity: " + result.who.flattenToShortString());
}
if (result.thisTime >= 0) {
System.out.println("ThisTime: " + result.thisTime);
}
if (result.totalTime >= 0) {
System.out.println("TotalTime: " + result.totalTime);
}
System.out.println("WaitTime: " + (endTime-startTime));
System.out.println("Complete");
在这个初始化时就已经进行了时间的计算:
frameworks\base\services\core\java\com\android\server\am\ActivityRecord.java 文件中计算
void windowsDrawnLocked() --->reportLaunchTimeLocked(SystemClock.uptimeMillis())
中完成时间的统计;
private void reportLaunchTimeLocked(final long curTime) {
final ActivityStack stack = task.stack;
if (stack == null) {
return;
}
final long thisTime = curTime - displayStartTime;
final long totalTime = stack.mLaunchStartTime != 0
? (curTime - stack.mLaunchStartTime) : thisTime;
if (SHOW_ACTIVITY_START_TIME) {
Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER, "launching: " + packageName, 0);
EventLog.writeEvent(EventLogTags.AM_ACTIVITY_LAUNCH_TIME,
userId, System.identityHashCode(this), shortComponentName,
thisTime, totalTime);
StringBuilder sb = service.mStringBuilder;
sb.setLength(0);
sb.append("Displayed ");
sb.append(shortComponentName);
sb.append(": ");
TimeUtils.formatDuration(thisTime, sb);
if (thisTime != totalTime) {
sb.append(" (total ");
TimeUtils.formatDuration(totalTime, sb);
sb.append(")");
}
Log.i(TAG, sb.toString());
}
mStackSupervisor.reportActivityLaunchedLocked(false, this, thisTime, totalTime);
if (totalTime > 0) {
//service.mUsageStatsService.noteLaunchTime(realActivity, (int)totalTime);
}
displayStartTime = 0;
stack.mLaunchStartTime = 0;
}
Debug.startMethodTracing(filePath);
//中间为需要统计执行时间的代码
Debug.stopMethodTracing();
adb pull /storage/emulated/0/app1.trace 把文件拉出来分析
把pull到电脑上的文件拖到AS中就可以分析了
优化方案:
1.开线程 没建handler 没操作UI 对异步要求不高
2.懒加载 用到的时候再初始化,如网络,数据库操作
public class App extends Application {
@Override
public void onCreate() {
super.onCreate();
File file = new File(Environment.getExternalStorageDirectory(), "app1.trace");
Log.i(TAG, "onCreate: " + file.getAbsolutePath());
//把分析结果存在一个文件
Debug.startMethodTracing(file.getAbsolutePath());
//对全局属性赋值
mContext = getApplicationContext();
mMainThread = Thread.currentThread();
mMainThreadId = android.os.Process.myTid();
mMainLooper = getMainLooper();
mHandler = new Handler();
//因为LQRUIKit中已经对ImageLoader进行过初始化了
//initImageLoader(getApplicationContext());
new Thread(){
@Override
public void run() {
//如果要用线程来节约了这些初始化的时间
//1.里面的API不能去创建handler
//2.不能有UI操作
//3.对异步要求不高
initNim();
initImagePicker();
initOkHttp();//可以懒加载
}
}.start();
initNim();
initImagePicker();
initOkHttp();//可以懒加载
NIMClient.init(this, loginInfo(), options());
Debug.stopMethodTracing();
}
...
}