/android/GT_APP/datatool/src/main/java/com/tencent/wstt/gt/datatool/analysis/FragmentAnalysis.java

https://github.com/Tencent/GT · Java · 419 lines · 335 code · 64 blank · 20 comment · 104 complexity · 1a7a912f9d8ea1efd2bb7ee106fb7238 MD5 · raw file

  1. package com.tencent.wstt.gt.datatool.analysis;
  2. import com.alibaba.fastjson.JSON;
  3. import com.tencent.wstt.gt.datatool.GTRAnalysis;
  4. import com.tencent.wstt.gt.datatool.obj.FragmentInfo;
  5. import com.tencent.wstt.gt.datatool.obj.FragmentLifecycleMethod;
  6. import java.util.ArrayList;
  7. public class FragmentAnalysis {
  8. ArrayList<FragmentInfo> fragmentInfos;
  9. ArrayList<Integer> overFragments;
  10. public FragmentAnalysis(GTRAnalysis gtrAnalysis, ArrayList<FragmentInfo> fragmentInfos, ArrayList<Integer> overFragments) {
  11. this.fragmentInfos = fragmentInfos;
  12. this.overFragments = overFragments;
  13. }
  14. /**
  15. * 冷启动:从onAttach函数开始
  16. * 热启动:从onCreateView或onStart函数开始
  17. * 1.ViewPager的回退栈:会引起 onCreateView - onDestroyView 的生命周期
  18. * 2.Activity的回退栈:会引起 onStart - onStop 的生命周期
  19. */
  20. private final Object lock = new Object();
  21. private int startNumber = 0;//启动页面的数量,用于赋值给startOrderId
  22. //onAttach列表:加入列表中
  23. private ArrayList<FragmentInfo> onAttachList = new ArrayList<>();
  24. //onCreateView列表:
  25. private ArrayList<FragmentInfo> onCreateViewList = new ArrayList<>();
  26. //fragment列表:
  27. // 1.onStart,加入列表中
  28. // 2.onStop,从表中移除,写入文件
  29. private ArrayList<FragmentInfo> fragmentInfoList = new ArrayList<>();
  30. private final Object stateLock = new Object();
  31. //Fragment状态列表:
  32. // 1.onAttach时加入
  33. // 2.onDetach时移除列表
  34. private ArrayList<FragmentState> fragmentStateList = new ArrayList<>();
  35. public void onFragment_onAttach(String activityClassName, String activityHashCode, String fragmentClassName,
  36. String fragmentHashCode, long start, long end) {
  37. synchronized (lock) {
  38. FragmentInfo fragmentInfo = new FragmentInfo(activityClassName, activityHashCode, fragmentClassName, fragmentHashCode);
  39. fragmentInfo.addAttachInfo(start, end);
  40. onAttachList.add(fragmentInfo);
  41. }
  42. }
  43. public void onFragment_performCreate(String activityClassName, String activityHashCode, String fragmentClassName,
  44. String fragmentHashCode, long start, long end) {
  45. synchronized (lock) {
  46. for (FragmentInfo fragmentInfo : onAttachList) {
  47. if (fragmentInfo.activityClassName.equals(activityClassName)
  48. && fragmentInfo.activityHashCode.equals(activityHashCode)
  49. && fragmentInfo.fragmentClassName.equals(fragmentClassName)
  50. && fragmentInfo.fragmentHashCode.equals(fragmentHashCode)) {
  51. fragmentInfo.addCreateInfo(start, end);
  52. break;
  53. }
  54. }
  55. }
  56. }
  57. public void onFragment_performCreateView(String activityClassName, String activityHashCode,
  58. String fragmentClassName, String fragmentHashCode, long start, long end) {
  59. synchronized (lock) {
  60. FragmentInfo fragmentHasAttach = null;
  61. for (FragmentInfo fragmentInfo : onAttachList) {
  62. if (fragmentInfo.activityClassName.equals(activityClassName)
  63. && fragmentInfo.activityHashCode.equals(activityHashCode)
  64. && fragmentInfo.fragmentClassName.equals(fragmentClassName)
  65. && fragmentInfo.fragmentHashCode.equals(fragmentHashCode)) {
  66. fragmentHasAttach = fragmentInfo;
  67. onAttachList.remove(fragmentInfo);
  68. break;
  69. }
  70. }
  71. if (fragmentHasAttach == null) {
  72. fragmentHasAttach = new FragmentInfo(activityClassName, activityHashCode, fragmentClassName, fragmentHashCode);
  73. }
  74. fragmentHasAttach.addCreateViewInfo(start, end);
  75. onCreateViewList.add(fragmentHasAttach);
  76. }
  77. }
  78. public void onFragment_performActivityCreated(String activityClassName, String activityHashCode,
  79. String fragmentClassName, String fragmentHashCode, long start, long end) {
  80. synchronized (lock) {
  81. for (FragmentInfo fragmentInfo : onCreateViewList) {
  82. if (fragmentInfo.activityClassName.equals(activityClassName)
  83. && fragmentInfo.activityHashCode.equals(activityHashCode)
  84. && fragmentInfo.fragmentClassName.equals(fragmentClassName)
  85. && fragmentInfo.fragmentHashCode.equals(fragmentHashCode)) {
  86. fragmentInfo.addActivityCreatedInfo(start, end);
  87. break;
  88. }
  89. }
  90. }
  91. }
  92. public void onFragment_performStart(String activityClassName, String activityHashCode, String fragmentClassName,
  93. String fragmentHashCode, long start, long end) {
  94. synchronized (lock) {
  95. FragmentInfo fragmentHasCreateView = null;
  96. for (FragmentInfo fragmentInfo : onCreateViewList) {
  97. if (fragmentInfo.activityClassName.equals(activityClassName)
  98. && fragmentInfo.activityHashCode.equals(activityHashCode)
  99. && fragmentInfo.fragmentClassName.equals(fragmentClassName)
  100. && fragmentInfo.fragmentHashCode.equals(fragmentHashCode)) {
  101. fragmentHasCreateView = fragmentInfo;
  102. onCreateViewList.remove(fragmentInfo);
  103. break;
  104. }
  105. }
  106. if (fragmentHasCreateView == null) {
  107. fragmentHasCreateView = new FragmentInfo(activityClassName, activityHashCode, fragmentClassName, fragmentHashCode);
  108. }
  109. fragmentHasCreateView.addStartInfo(start, end);
  110. fragmentInfoList.add(fragmentHasCreateView);
  111. }
  112. }
  113. public void onFragment_performResume(String activityClassName, String activityHashCode, String fragmentClassName,
  114. String fragmentHashCode, long start, long end) {
  115. synchronized (lock) {
  116. for (FragmentInfo fragmentInfo : fragmentInfoList) {
  117. if (fragmentInfo.activityClassName.equals(activityClassName)
  118. && fragmentInfo.activityHashCode.equals(activityHashCode)
  119. && fragmentInfo.fragmentClassName.equals(fragmentClassName)
  120. && fragmentInfo.fragmentHashCode.equals(fragmentHashCode)) {
  121. fragmentInfo.addResumeInfo(start, end);
  122. startNumber++;
  123. fragmentInfo.startOrderId = startNumber;
  124. break;
  125. }
  126. }
  127. }
  128. synchronized (stateLock) {
  129. FragmentState fragmentToShow = null;
  130. for (FragmentState fragmentState : fragmentStateList) {
  131. if (fragmentState.fragmentClassName.equals(fragmentClassName)
  132. && fragmentState.fragmentHashCode.equals(fragmentHashCode)) {
  133. fragmentToShow = fragmentState;
  134. break;
  135. }
  136. }
  137. if (fragmentToShow == null) {
  138. fragmentToShow = new FragmentState(fragmentClassName, fragmentHashCode);
  139. fragmentStateList.add(fragmentToShow);
  140. }
  141. fragmentToShow.hasResumed = true;
  142. if (fragmentToShow.isShow()) {
  143. fragmentToShow.showStart = System.currentTimeMillis();
  144. }
  145. }
  146. }
  147. public void onFragment_performPause(String activityClassName, String activityHashCode, String fragmentClassName,
  148. String fragmentHashCode, long start, long end) {
  149. synchronized (lock) {
  150. for (FragmentInfo fragmentInfo : fragmentInfoList) {
  151. if (fragmentInfo.activityClassName.equals(activityClassName)
  152. && fragmentInfo.activityHashCode.equals(activityHashCode)
  153. && fragmentInfo.fragmentClassName.equals(fragmentClassName)
  154. && fragmentInfo.fragmentHashCode.equals(fragmentHashCode)) {
  155. fragmentInfo.addPauseInfo(start, end);
  156. break;
  157. }
  158. }
  159. }
  160. synchronized (stateLock) {
  161. FragmentState fragmentToShow = null;
  162. for (FragmentState fragmentState : fragmentStateList) {
  163. if (fragmentState.fragmentClassName.equals(fragmentClassName)
  164. && fragmentState.fragmentHashCode.equals(fragmentHashCode)) {
  165. fragmentToShow = fragmentState;
  166. break;
  167. }
  168. }
  169. if (fragmentToShow == null) {
  170. fragmentToShow = new FragmentState(fragmentClassName, fragmentHashCode);
  171. fragmentStateList.add(fragmentToShow);
  172. }
  173. if (fragmentToShow.isShow() && fragmentToShow.showStart != 0) {//匹配fragment的显示时间
  174. addFragmentVisibleInfo(fragmentClassName, fragmentHashCode, fragmentToShow.showStart, System.currentTimeMillis());
  175. }
  176. fragmentToShow.hasResumed = false;
  177. fragmentToShow.showStart = 0;
  178. }
  179. }
  180. public void onFragment_performStop(String activityClassName, String activityHashCode, String fragmentClassName,
  181. String fragmentHashCode, long start, long end) {
  182. synchronized (lock) {
  183. for (FragmentInfo fragmentInfo : fragmentInfoList) {
  184. if (fragmentInfo.activityClassName.equals(activityClassName)
  185. && fragmentInfo.activityHashCode.equals(activityHashCode)
  186. && fragmentInfo.fragmentClassName.equals(fragmentClassName)
  187. && fragmentInfo.fragmentHashCode.equals(fragmentHashCode)) {
  188. fragmentInfo.addStopInfo(start, end);
  189. // 写入文件
  190. if (fragmentInfo.startOrderId != 0) {//等于零 表示没有执行onResume函数
  191. fragmentInfos.add(fragmentInfo);
  192. //记录超时
  193. long loadTime = getFragmentStartFinishTime(fragmentInfo) - getFragmentStartTime(fragmentInfo);
  194. if (loadTime > 300) {
  195. System.out.println(JSON.toJSONString(fragmentInfo));
  196. boolean isExists = false;
  197. for (int h = 0; h < overFragments.size(); h++) {
  198. FragmentInfo overFragment = fragmentInfos.get(overFragments.get(h));
  199. if (overFragment.fragmentClassName.equals(fragmentInfo.fragmentClassName)) {
  200. isExists = true;
  201. if (loadTime > getFragmentStartFinishTime(overFragment) - getFragmentStartTime(overFragment)) {
  202. overFragments.remove(h);
  203. overFragments.add(fragmentInfos.size() - 1);
  204. }
  205. break;
  206. }
  207. }
  208. if (!isExists) {
  209. overFragments.add(fragmentInfos.size() - 1);
  210. }
  211. }
  212. }
  213. //移除队列
  214. fragmentInfoList.remove(fragmentInfo);
  215. break;
  216. }
  217. }
  218. }
  219. }
  220. public void onFragment_performDestroyView(String activityClassName, String activityHashCode,
  221. String fragmentClassName, String fragmentHashCode, long start, long end) {
  222. //do nothing
  223. }
  224. public void onFragment_performDestroy(String activityClassName, String activityHashCode, String fragmentClassName,
  225. String fragmentHashCode, long start, long end) {
  226. //do nothing
  227. }
  228. public void onFragment_performDetach(String activityClassName, String activityHashCode, String fragmentClassName,
  229. String fragmentHashCode, long start, long end) {
  230. //do nothing
  231. synchronized (stateLock) {
  232. for (FragmentState fragmentState : fragmentStateList) {
  233. if (fragmentState.fragmentClassName.equals(fragmentClassName)
  234. && fragmentState.fragmentHashCode.equals(fragmentHashCode)) {
  235. fragmentStateList.remove(fragmentState);
  236. break;
  237. }
  238. }
  239. }
  240. }
  241. public void onFragment_onHiddenChanged(String activityClassName, String activityHashCode, String fragmentClassName,
  242. String fragmentHashCode, long time, boolean hidden) {
  243. synchronized (stateLock) {
  244. FragmentState fragmentToShow = null;
  245. for (FragmentState fragmentState : fragmentStateList) {
  246. if (fragmentState.fragmentClassName.equals(fragmentClassName)
  247. && fragmentState.fragmentHashCode.equals(fragmentHashCode)) {
  248. fragmentToShow = fragmentState;
  249. break;
  250. }
  251. }
  252. if (fragmentToShow == null) {
  253. fragmentToShow = new FragmentState(fragmentClassName, fragmentHashCode);
  254. fragmentStateList.add(fragmentToShow);
  255. }
  256. if (!hidden) {
  257. fragmentToShow.hasShow = true;
  258. if (fragmentToShow.isShow()) {
  259. fragmentToShow.showStart = System.currentTimeMillis();
  260. }
  261. } else {
  262. if (fragmentToShow.isShow() && fragmentToShow.showStart != 0) {//匹配fragment的显示时间
  263. addFragmentVisibleInfo(fragmentClassName, fragmentHashCode, fragmentToShow.showStart, System.currentTimeMillis());
  264. }
  265. fragmentToShow.hasShow = false;
  266. fragmentToShow.showStart = 0;
  267. }
  268. }
  269. }
  270. public void onFragment_setUserVisibleHint(String activityClassName, String activityHashCode,
  271. String fragmentClassName, String fragmentHashCode, long time, boolean isVisibleToUser) {
  272. synchronized (stateLock) {
  273. FragmentState fragmentToShow = null;
  274. for (FragmentState fragmentState : fragmentStateList) {
  275. if (fragmentState.fragmentClassName.equals(fragmentClassName)
  276. && fragmentState.fragmentHashCode.equals(fragmentHashCode)) {
  277. fragmentToShow = fragmentState;
  278. break;
  279. }
  280. }
  281. if (fragmentToShow == null) {
  282. fragmentToShow = new FragmentState(fragmentClassName, fragmentHashCode);
  283. fragmentStateList.add(fragmentToShow);
  284. }
  285. if (isVisibleToUser) {
  286. fragmentToShow.hasVisible = true;
  287. if (fragmentToShow.isShow()) {
  288. fragmentToShow.showStart = System.currentTimeMillis();
  289. }
  290. } else {
  291. if (fragmentToShow.isShow() && fragmentToShow.showStart != 0) {//匹配fragment的显示时间
  292. addFragmentVisibleInfo(fragmentClassName, fragmentHashCode, fragmentToShow.showStart, System.currentTimeMillis());
  293. }
  294. fragmentToShow.hasVisible = false;
  295. fragmentToShow.showStart = 0;
  296. }
  297. }
  298. }
  299. private void addFragmentVisibleInfo(String fragmentClassName, String fragmentHashCode, long showStart, long shouEnd) {
  300. synchronized (lock) {
  301. for (FragmentInfo fragmentInfo : fragmentInfoList) {
  302. if (fragmentInfo.fragmentClassName.equals(fragmentClassName)
  303. && fragmentInfo.fragmentHashCode.equals(fragmentHashCode)) {
  304. fragmentInfo.addVisibleInfo(showStart, shouEnd);
  305. break;
  306. }
  307. }
  308. }
  309. }
  310. private static class FragmentState {
  311. public String fragmentClassName = "";
  312. public String fragmentHashCode = "";
  313. public boolean hasResumed = false; //此值由Fragment.onResume 和 Fragment.onPause 函数决定。
  314. public boolean hasShow = true;//此值由onHiddenChanged函数决定
  315. public boolean hasVisible = true; //此值由setUserVisibleHint函数决定
  316. public long showStart = 0;
  317. public FragmentState(String fragmentClassName, String fragmentHashCode) {
  318. this.fragmentClassName = fragmentClassName;
  319. this.fragmentHashCode = fragmentHashCode;
  320. }
  321. public String getState() {
  322. if (hasResumed && hasShow && hasVisible) {
  323. return fragmentClassName + "," + fragmentHashCode + "," + "显示";
  324. } else {
  325. return fragmentClassName + "," + fragmentHashCode + "," + "隐藏";
  326. }
  327. }
  328. public boolean isShow() {
  329. if (hasResumed && hasShow && hasVisible) {
  330. return true;
  331. } else {
  332. return false;
  333. }
  334. }
  335. }
  336. private static long getFragmentStartTime(FragmentInfo fragmentInfo) {
  337. long start = 0;
  338. for (FragmentLifecycleMethod lifecycleMethod : fragmentInfo.fragmentLifecycleMethodList) {
  339. if (start == 0 || lifecycleMethod.methodStartTime < start) {
  340. start = lifecycleMethod.methodStartTime;
  341. }
  342. }
  343. return start;
  344. }
  345. private static long getFragmentStartFinishTime(FragmentInfo fragmentInfo) {
  346. long startFinish = 0;
  347. for (FragmentLifecycleMethod lifecycleMethod : fragmentInfo.fragmentLifecycleMethodList) {
  348. if (startFinish == 0 || lifecycleMethod.methodName.equals(FragmentLifecycleMethod.ONRESUME)) {
  349. startFinish = lifecycleMethod.methodEndTime;
  350. return startFinish;
  351. }
  352. }
  353. return startFinish;
  354. }
  355. }