package com.glview.hwui; import android.os.Build; import android.os.Process; import android.os.StrictMode; import android.os.StrictMode.ThreadPolicy; import android.util.Log; import com.glview.App; import com.glview.libgdx.graphics.opengl.AndroidGL20; import com.glview.thread.Looper; class RenderThread extends Thread { final static String TAG = "RenderThread"; final static boolean DEBUG = false; private static Looper sMainLooper; private static RenderThread sMainThread; private Looper mLooper; private RenderThread() { } private static void ensureRenderThread() { if (sMainThread == null || !sMainThread.isAlive()) { sMainThread = new RenderThread(); sMainThread.start(); sMainLooper = sMainThread.getLooper(); } } public static Looper getRenderThreadLooper() { ensureRenderThread(); return sMainLooper; } @Override public synchronized void start() { super.start(); } boolean checkThreadState() { return Looper.myLooper() == mLooper; } @Override public void run() { setName("RenderThread " + getId()); Log.i(TAG, "starting tid=" + getId()); init(); // 主线程,调用prepare(false),线程不允许被quit // try { // Log.i(TAG, "Try to prepare the looper with declaredMethod 'private static void android.os.Looper.prepare(boolean)' to set quitAllowed=false"); // Method m = Looper.class.getDeclaredMethod("prepare", boolean.class); // m.setAccessible(true); // m.invoke(null, false); // m.setAccessible(false); // } catch(Exception e) { // Log.w(TAG, "Reflection failed, use public prepare", e); // } // if (Looper.myLooper() == null) { // Looper.prepare(); // } Looper.prepare1(); App.setGL20(new AndroidGL20()); synchronized (this) { mLooper = Looper.myLooper(); notifyAll(); } intoLoop(); } void init() { Process.setThreadPriority(Process.THREAD_PRIORITY_DISPLAY); // disable network access in main thread if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { StrictMode.setThreadPolicy(new ThreadPolicy.Builder().detectNetwork().penaltyDeathOnNetwork().build()); } } void intoLoop() { Looper.loop(); } /** * This method returns the Looper associated with this thread. If this thread not been started * or for any reason is isAlive() returns false, this method will return null. If this thread * has been started, this method will block until the looper has been initialized. * @return The looper. */ public Looper getLooper() { if (!isAlive()) { return null; } // If the thread has been started, wait until the looper has been created. synchronized (this) { while (isAlive() && mLooper == null) { try { wait(); } catch (InterruptedException e) { } } } return mLooper; } }