can someone explain what what is going on here for which thread is being blocked? the thread object here is used for canvas and drawing graphics, the join() method is called on this graphics thread so it will continue to finish. while the other thread is blocked and waiting. which thread is this?
if the surfaceView class is running on the main UI thread than the UI will be blocked waiting for the graphics thread to finish. this does not make sense. so the other explanation would be for there to be three separate threads here. the main UI thread, the graphics thread where join() is being called on, and a third thread for surface view that is getting blocked while the graphics thread finishes
is there in fact three threads running, and the UI thread is not the one being blocked?
nowhere in my code did I start a new thread for SurfaceView. I only instantiated a SurfaceView object.
as this code is written it looks like the main UI thread is blocked waiting for the graphics thread to finish.
If the SurfaceView object is instantiated inside of a thread or AsyncTask then it would look more clear.
// this code is located inside of the SurfaceView class
@Override
public void surfaceCreated(SurfaceHolder holder) {
// can also put this code in surfaceChanged
running = true;
thread = new Thread(surfaceRunnable);
thread.start();
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
running = false;
boolean retry = true;
while(retry) {
try {
thread.join();
retry = false;
} catch( InterruptedException e) {
}
}
The thread that is blocked is the UI thread . Proving this with a debugger is a good idea. You can confirm this by viewing the source code of SurfaceView.java
(if in Eclipse, hit F3
while the cursor is on the text SurfaceView
). In particular:
The callbacks such as surfaceDestroyed()
are called from SurfaceView.updateWindow()
:
private void updateWindow(boolean force, boolean redrawNeeded) {
...
callbacks = getSurfaceCallbacks();
for (SurfaceHolder.Callback c : callbacks) {
c.surfaceDestroyed(mSurfaceHolder);
}
updateWindow()
is called from the anonymous class derived from Handler
and assigned to mHandler
:
final Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case KEEP_SCREEN_ON_MSG: {
setKeepScreenOn(msg.arg1 != 0);
} break;
case GET_NEW_SURFACE_MSG: {
handleGetNewSurface();
} break;
case UPDATE_WINDOW_MSG: {
updateWindow(false, false);
} break;
}
}
};
Note that this mHandler
object is constructed when the SurfaceView
object is constructed, which happens on the UI thread. And note that the Handler
constructor binds the Handler
to the Looper
associated with the current thread (the UI thread). So handleMesssage()
runs on that Looper
which is the UI thread's Looper
. Thus, updateWindow()
is called on the UI thread.
updateWindow()
is also called several other times in the file and most of the time it is easy to deduce that it is being called from the UI thread.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.