-
Notifications
You must be signed in to change notification settings - Fork 8.3k
/
Copy pathDispatchQueueMainThreadSync.java
169 lines (145 loc) · 4.34 KB
/
DispatchQueueMainThreadSync.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
package org.telegram.messenger;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.SystemClock;
import java.util.ArrayList;
public class DispatchQueueMainThreadSync extends Thread {
private volatile Handler handler = null;
private boolean isRunning;
private boolean isRecycled;
private long lastTaskTime;
private static int indexPointer = 0;
public final int index = indexPointer++;
private ArrayList<PostponedTask> postponedTasks = new ArrayList<>();
public DispatchQueueMainThreadSync(final String threadName) {
this(threadName, true);
}
public DispatchQueueMainThreadSync(final String threadName, boolean start) {
setName(threadName);
if (start) {
start();
}
}
public void sendMessage(Message msg, int delay) {
checkThread();
if (isRecycled) {
return;
}
if (!isRunning) {
postponedTasks.add(new PostponedTask(msg, delay));
return;
}
if (delay <= 0) {
handler.sendMessage(msg);
} else {
handler.sendMessageDelayed(msg, delay);
}
}
private void checkThread() {
if (BuildVars.DEBUG_PRIVATE_VERSION && Thread.currentThread() != ApplicationLoader.applicationHandler.getLooper().getThread()) {
// throw new IllegalStateException("Disaptch thread");
}
}
public void cancelRunnable(Runnable runnable) {
checkThread();
if (isRunning) {
handler.removeCallbacks(runnable);
} else {
for (int i = 0; i < postponedTasks.size(); i++) {
if (postponedTasks.get(i).runnable == runnable) {
postponedTasks.remove(i);
i--;
}
}
}
}
public void cancelRunnables(Runnable[] runnables) {
checkThread();
for (int i = 0; i < runnables.length; i++) {
cancelRunnable(runnables[i]);
}
}
public boolean postRunnable(Runnable runnable) {
checkThread();
lastTaskTime = SystemClock.elapsedRealtime();
return postRunnable(runnable, 0);
}
public boolean postRunnable(Runnable runnable, long delay) {
checkThread();
if (isRecycled) {
return false;
}
if (!isRunning) {
postponedTasks.add(new PostponedTask(runnable, delay));
return true;
}
if (delay <= 0) {
return handler.post(runnable);
} else {
return handler.postDelayed(runnable, delay);
}
}
public void cleanupQueue() {
checkThread();
postponedTasks.clear();
handler.removeCallbacksAndMessages(null);
}
public void handleMessage(Message inputMessage) {
}
public long getLastTaskTime() {
return lastTaskTime;
}
public void recycle() {
checkThread();
postRunnable(() -> {
handler.getLooper().quit();
});
isRecycled = true;
}
@Override
public void run() {
Looper.prepare();
handler = new Handler(Looper.myLooper(), msg -> {
DispatchQueueMainThreadSync.this.handleMessage(msg);
return true;
});
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
isRunning = true;
for (int i = 0; i < postponedTasks.size(); i++) {
postponedTasks.get(i).run();
}
postponedTasks.clear();
}
});
Looper.loop();
}
public boolean isReady() {
return isRunning;
}
public Handler getHandler() {
return handler;
}
private class PostponedTask {
Message message;
Runnable runnable;
long delay;
public PostponedTask(Message msg, int delay) {
this.message = msg;
this.delay = delay;
}
public PostponedTask(Runnable runnable, long delay) {
this.runnable = runnable;
this.delay = delay;
}
public void run() {
if (runnable != null) {
postRunnable(runnable, delay);
} else {
sendMessage(message, (int) delay);
}
}
}
}