Skip to content

Instantly share code, notes, and snippets.

@lightai
Created February 25, 2020 16:52
Show Gist options
  • Save lightai/bd06f1c81259c3200dfbfde58de9ee69 to your computer and use it in GitHub Desktop.
Save lightai/bd06f1c81259c3200dfbfde58de9ee69 to your computer and use it in GitHub Desktop.
android线程监测,排查性能问题
static class ThreadMonitor {
private void startThreadMonitor() {
final Thread mainThread = Thread.currentThread();
ThreadGroup threadGroup = mainThread.getThreadGroup();
final Thread[] allThread = new Thread[threadGroup.activeCount()];
threadGroup.enumerate(allThread);
final Map<Thread, ThreadStateTimeLine> timeLineMap = new HashMap<>(allThread.length);
for (Thread thread : allThread) {
timeLineMap.put(thread, new ThreadStateTimeLine(thread));
}
new Thread(new Runnable() {
@Override
public void run() {
Process.setThreadPriority(Process.THREAD_PRIORITY_FOREGROUND);
long time0 = SystemClock.uptimeMillis();
long time;
while ((time = SystemClock.uptimeMillis() - time0) < 3000) {
// for (Thread thread : allThread) {
Thread thread = mainThread;
Thread.State currState = thread.getState();
ThreadStateTimeLine timeLine = timeLineMap.get(thread);
ThreadStage threadStage;
if (timeLine.stateTimeLine.size() == 0) {
threadStage = new ThreadStage(currState);
threadStage.startUpMillis = time;
timeLine.stateTimeLine.add(threadStage);
} else {
threadStage = timeLine.stateTimeLine.get(
timeLine.stateTimeLine.size() - 1);
if (currState == threadStage.state) {
threadStage.endMillis = time;
threadStage.time = threadStage.endMillis - threadStage.startUpMillis;
} else {
threadStage.endMillis = time;
threadStage.time = threadStage.endMillis - threadStage.startUpMillis;
threadStage = new ThreadStage(currState);
threadStage.startUpMillis = time;
timeLine.stateTimeLine.add(threadStage);
}
if (currState == Thread.State.BLOCKED || currState == Thread.State.WAITING) {
StackTraceElement[] elements = mainThread.getStackTrace();
if (threadStage.stackTraceElements == null) {
threadStage.stackTraceElements = elements;
} else {
if (threadStage.stackTraceElements.length != elements.length) {
threadStage = new ThreadStage(currState);
threadStage.startUpMillis = time;
threadStage.stackTraceElements = elements;
timeLine.stateTimeLine.add(threadStage);
}
}
}
}
// }
}
Object[] threadStages = null;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
threadStages = timeLineMap.get(mainThread).stateTimeLine
.stream()
.filter(new Predicate<ThreadStage>() {
@Override
public boolean test(ThreadStage threadStage) {
return threadStage.state == Thread.State.BLOCKED;
}
})
.toArray();
}
String result = JSON.toJSONString(threadStages);
File file = new File("/sdcard/result.json");
file.setWritable(true);
try {
new FileOutputStream(file).write(result.getBytes());
} catch (IOException e) {
e.printStackTrace();
}
Log.e(TAG, "main thread:"
+ result);
}
}).start();
}
static class ThreadStateTimeLine {
Thread thread;
List<ThreadStage> stateTimeLine = new ArrayList<>(1000);
public ThreadStateTimeLine(Thread thread) {
this.thread = thread;
}
}
static class ThreadStage {
public long startUpMillis;
public long endMillis;
public Thread.State state;
public long time;
public StackTraceElement[] stackTraceElements;
public ThreadStage(Thread.State currState) {
this.state = currState;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment