(1)外部引起的:Activity里面直接进行网络访问/大文件的IO操作。
(2)内存引起的:内存抖动的问题,new Object obj = null;执行耗时方法。
(3)View本身的卡顿:自定义View要注意的,能否优化:
(1)避免让主线程执行耗时的操作
(2)优化自定义View卡顿问题
参考链接:性能优化之内存泄露(Memory Leak)常用分析工具(另3种)
————>第三部分:3 Allaction Tracking(Android Studio版)
从代码层面分析性能问题,针对每个方法来分析,比如当我们发现我们的应用出现卡顿的时候,我们可以来分析出现卡顿时在方法的调用上有没有很耗时的操作,关注以下两个问题:
(1)调用次数不多,但是每一次执行都很耗时
(2)方法耗时不大,但是调用次数太多
简单一点来说就是:我们能找到频繁被调用的方法,也能找到执行非常耗时的方法,前者可能会造成Cpu频繁调用,手机发烫的问题,后者就是卡顿的问题
Android性能专项测试之TraceView工具(Device Monitor)
(1)打开App操作应用后,start开始追踪,点击stop后停止追踪并且自动打开traceview分析面板:
(2)打开traceview分析面板:
展开一个方法后可以看到有两部分:Parent表示调用这个方法的方法,可以叫做父方法;Children表示这个方法中调用的其他方法,可以叫做子方法。
Profile面板中各列作用说明:
(1)图例演示
(2)找到问题所在:rowAsStr += “, “;
/**
* com.example.android.mobileperf.compute.MemoryChurnActivity的以下方法:
* 排序后打印二维数组,一行行打印
*/
public void imPrettySureSortingIsFree() {
// 优化以前
int dimension = 300;
int[][] lotsOfInts = new int[dimension][dimension];
Random randomGenerator = new Random();
for(int i = 0; i < lotsOfInts.length; i++) {
for (int j = 0; j < lotsOfInts[i].length; j++) {
lotsOfInts[i][j] = randomGenerator.nextInt();
}
}
for(int i = 0; i < lotsOfInts.length; i++) {
String rowAsStr = "";
//排序
int[] sorted = getSorted(lotsOfInts[i]);
//拼接打印
for (int j = 0; j < lotsOfInts[i].length; j++) {
rowAsStr += sorted[j];
if(j < (lotsOfInts[i].length - 1)){
rowAsStr += ", ";
}
}
}
//优化以后
// StringBuilder sb = new StringBuilder();
// String rowAsStr = "";
// for(int i = 0; i < lotsOfInts.length; i++) {
// //清除上一行
// sb.delete(0,rowAsStr.length());
// //排序
// int[] sorted = getSorted(lotsOfInts[i]);
// //拼接打印
// for (int j = 0; j < lotsOfInts[i].length; j++) {
//// rowAsStr += sorted[j];
// sb.append(sorted[j]);
// if(j < (lotsOfInts[i].length - 1)){
//// rowAsStr += ", ";
// sb.append(", ");
// }
// }
// rowAsStr = sb.toString();
// Log.i("ricky", "Row " + i + ": " + rowAsStr);
// }
}
// com.example.android.mobileperf.compute.CachingActivity
//优化前
public int computeFibonacci(int pInFibSequence) {
//0 1 1 2 3 5 8
if (pInFibSequence <= 2) {
return 1;
} else {
return computeFibonacci(pInFibSequence - 1)+ computeFibonacci(pInFibSequence - 2);
}
}
//优化后的斐波那契数列的非递归算法 caching缓存+批处理思想
public int computeFibonacci(int pInFibSequence) {
int prev = 0;
int current = 1;
int newValue;
for (int i=1; ireturn current;
}
(3)解决问题思路
尽量避免让【主线程】执行耗时的操作,让它能快速处理UI事件和Broadcast消息。
(1)在onCreate开始和结尾打上trace.
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Debug.startMethodTracing("textracing");//开始
sleep();
login();
Debug.stopMethodTracing();//结束
}
private void sleep() {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
(2)运行程序, 会在手机sdcard或者本地存储上生成一个”textracing.trace”的文件。注意: 需要给程序加上写存储的权限:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
(3)MAC:通过adb pull将其导出到本地,然后将textracing.trace从手机传到电脑上
adb pull /sdcard/Traceview.trace ~/temp
(4)Windows:直接将textracing.trace从手机传到电脑上(textracing.trace存放在根目录)
Android UI性能优化 检测应用中的UI卡顿