@Override public void onLoadResult(File patchDirectory, int loadCode, long cost) { super.onLoadResult(patchDirectory, loadCode, cost); switch (loadCode) { case ShareConstants.ERROR_LOAD_OK: SampleTinkerReport.onLoaded(cost); break; } Looper.getMainLooper().myQueue().addIdleHandler(new MessageQueue.IdleHandler() { @Override public boolean queueIdle() { UpgradePatchRetry.getInstance(context).onPatchRetryLoad(); return false; } }); }
@Override public void onLoadResult(File patchDirectory, int loadCode, long cost) { super.onLoadResult(patchDirectory, loadCode, cost); switch (loadCode) { case ShareConstants.ERROR_LOAD_OK: SampleTinkerReport.onLoaded(cost); break; } Looper.getMainLooper().myQueue().addIdleHandler(new MessageQueue.IdleHandler() { @Override public boolean queueIdle() { if (UpgradePatchRetry.getInstance(context).onPatchRetryLoad()) { SampleTinkerReport.onReportRetryPatch(); } return false; } }); }
@Override public void onCreate() { super.onCreate(); instance = this; Global.init(this); LeakCanary.install(this); // CrashHandler.getInstance().init(this); Looper.myQueue().addIdleHandler(new MessageQueue.IdleHandler() { @Override public boolean queueIdle() { KeepAliveWatcher.keepAlive(BigBangApp.this); startService(new Intent(BigBangApp.this, ListenClipboardService.class)); startService(new Intent(BigBangApp.this, BigBangMonitorService.class)); return false; } }); AppManager.getInstance(this); }
/** * Add the idle handler which will run deferred startup tasks in sequence when idle. This can * be called multiple times by different activities to schedule their own deferred startup * tasks. */ public void queueDeferredTasksOnIdleHandler() { mMaxTaskDuration = 0; mDeferredStartupDuration = 0; Looper.myQueue().addIdleHandler(new MessageQueue.IdleHandler() { @Override public boolean queueIdle() { Runnable currentTask = mDeferredTasks.poll(); if (currentTask == null) { if (mDeferredStartupInitializedForApp) { mDeferredStartupCompletedForApp = true; recordDeferredStartupStats(); } return false; } long startTime = SystemClock.uptimeMillis(); currentTask.run(); long timeTaken = SystemClock.uptimeMillis() - startTime; mMaxTaskDuration = Math.max(mMaxTaskDuration, timeTaken); mDeferredStartupDuration += timeTaken; return true; } }); }
private void testInject() { Looper.myQueue().addIdleHandler(new MessageQueue.IdleHandler() { @Override public boolean queueIdle() { TestInject annotation = BActivity.this.getClass().getAnnotation(TestInject.class); if (annotation != null) { if (annotation.value() != null) { startActivity(new Intent(BActivity.this, annotation.value())); } } return false; } }); }
/** * 这个是无论加载失败或者成功都会回调的接口。 * 它返回了本次加载所用的时间、返回码等信息。 * 默认我们只是简单的输出这个信息,你可以在这里加上监控上报逻辑。 */ @Override public void onLoadResult(File patchDirectory, int loadCode, long cost) { super.onLoadResult(patchDirectory, loadCode, cost); switch (loadCode) { case ShareConstants.ERROR_LOAD_OK: SampleTinkerReport.onLoaded(cost); break; } Looper.getMainLooper().myQueue().addIdleHandler(new MessageQueue.IdleHandler() { @Override public boolean queueIdle() { if (UpgradePatchRetry.getInstance(context).onPatchRetryLoad()) { SampleTinkerReport.onReportRetryPatch(); } return false; } }); }
@Override public void onLoadResult(File patchDirectory, int loadCode, long cost) { super.onLoadResult(patchDirectory, loadCode, cost); switch (loadCode) { case ShareConstants.ERROR_LOAD_OK: PatchManager.getInstance().onLoadSuccess(); SampleTinkerReport.onLoaded(cost); break; default: break; } Looper.getMainLooper().myQueue().addIdleHandler(new MessageQueue.IdleHandler() { @Override public boolean queueIdle() { if (UpgradePatchRetry.getInstance(context).onPatchRetryLoad()) { SampleTinkerReport.onReportRetryPatch(); } return false; } }); }
private void showToast(final FutureResult<Toast> waitingForToast) { mainHandler.post(new Runnable() { @Override public void run() { final Toast toast = new Toast(context); toast.setGravity(Gravity.CENTER_VERTICAL, 0, 0); toast.setDuration(Toast.LENGTH_LONG); LayoutInflater inflater = LayoutInflater.from(context); toast.setView(inflater.inflate(R.layout.leak_canary_heap_dump_toast, null)); toast.setDuration(Toast.LENGTH_LONG); toast.show(); // Waiting for Idle to make sure Toast gets rendered. Looper.myQueue().addIdleHandler(new MessageQueue.IdleHandler() { @Override public boolean queueIdle() { waitingForToast.set(toast); return false; } }); } }); }
private void showToast(final FutureResult<Toast> waitingForToast) { mainHandler.post(new Runnable() { @Override public void run() { final Toast toast = new Toast(context); toast.setGravity(Gravity.CENTER_VERTICAL, 0, 0); toast.setDuration(Toast.LENGTH_LONG); LayoutInflater inflater = LayoutInflater.from(context); toast.setView(inflater.inflate(R.layout.leak_canary_heap_dump_toast, null)); toast.show(); // Waiting for Idle to make sure Toast gets rendered. Looper.myQueue().addIdleHandler(new MessageQueue.IdleHandler() { @Override public boolean queueIdle() { waitingForToast.set(toast); return false; } }); } }); }
/** * 检查服务器是否有补丁更新 * @param immediately 是否立刻检查,忽略时间间隔限制 */ public static void checkTinkerUpdate(final boolean immediately) { if (sTinkerServerClient == null) { TinkerLog.e(TAG, "checkTinkerUpdate, sTinkerServerClient == null"); return; } Tinker tinker = sTinkerServerClient.getTinker(); //only check at the main process if (tinker.isMainProcess()) { Looper.getMainLooper().myQueue().addIdleHandler(new MessageQueue.IdleHandler() { @Override public boolean queueIdle() { sTinkerServerClient.checkTinkerUpdate(immediately); return false; } }); } }
/** * 向服务器请求在线参数信息 * @param configRequestCallback * @param immediately 是否立刻请求,忽略时间间隔限制 */ public static void getDynamicConfig(final ConfigRequestCallback configRequestCallback, final boolean immediately) { if (sTinkerServerClient == null) { TinkerLog.e(TAG, "checkTinkerUpdate, sTinkerServerClient == null"); return; } Tinker tinker = sTinkerServerClient.getTinker(); //only check at the main process if (tinker.isMainProcess()) { Looper.getMainLooper().myQueue().addIdleHandler(new MessageQueue.IdleHandler() { @Override public boolean queueIdle() { sTinkerServerClient.getDynamicConfig(configRequestCallback, immediately); return false; } }); } }
private final void postDeferredStartupIfNeeded() { if (!mDeferredStartupNotified) { // We want to perform deferred startup tasks a short time after the first page // load completes, but only when the main thread Looper has become idle. mHandler.postDelayed(new Runnable() { @Override public void run() { if (!mDeferredStartupNotified && !isActivityDestroyed()) { mDeferredStartupNotified = true; Looper.myQueue().addIdleHandler(new MessageQueue.IdleHandler() { @Override public boolean queueIdle() { onDeferredStartup(); return false; // Remove this idle handler. } }); } } }, DEFERRED_STARTUP_DELAY_MS); } }
/** * Add the idle handler which will run deferred startup tasks in sequence when idle. This can * be called multiple times by different activities to schedule their own deferred startup * tasks. */ public void queueDeferredTasksOnIdleHandler() { mMaxTaskDuration = 0; mDeferredStartupDuration = 0; Looper.myQueue().addIdleHandler(new MessageQueue.IdleHandler() { @Override public boolean queueIdle() { Runnable currentTask = mDeferredTasks.poll(); if (currentTask == null) { if (!mDeferredStartupCompletedForApp) { mDeferredStartupCompletedForApp = true; recordDeferredStartupStats(); } return false; } long startTime = SystemClock.uptimeMillis(); currentTask.run(); long timeTaken = SystemClock.uptimeMillis() - startTime; mMaxTaskDuration = Math.max(mMaxTaskDuration, timeTaken); mDeferredStartupDuration += timeTaken; return true; } }); }
@Override public void onCreate() { super.onCreate(); // Delay TracingControllerAndroid.registerReceiver() until the main loop is idle. Looper.myQueue().addIdleHandler(new MessageQueue.IdleHandler() { @Override public boolean queueIdle() { // Will retry if the native library has not been initialized. if (!LibraryLoader.isInitialized()) return true; try { getTracingController().registerReceiver(ContentApplication.this); } catch (SecurityException e) { // Happens if the process is isolated. Ignore. } // Remove the idle handler. return false; } }); mLibraryDependenciesInitialized = true; }
private void initializeQueue() { if (interrogatedLooper == Looper.myLooper()) { interrogatedQueue = Looper.myQueue(); } else { Handler oneShotHandler = new Handler(interrogatedLooper); FutureTask<MessageQueue> queueCapture = new FutureTask<MessageQueue>( new Callable<MessageQueue>() { @Override public MessageQueue call() { return Looper.myQueue(); } }); oneShotHandler.postAtFrontOfQueue(queueCapture); try { interrogatedQueue = queueCapture.get(); } catch (ExecutionException ee) { throw propagate(ee.getCause()); } catch (InterruptedException ie) { throw propagate(ie); } } }
@Override public void onCreate() { super.onCreate(); // Delay TracingControllerAndroid.registerReceiver() until the main loop is idle. Looper.myQueue().addIdleHandler(new MessageQueue.IdleHandler() { @Override public boolean queueIdle() { // Will retry if the native library has not been initialized. if (!LibraryLoader.isInitialized()) return true; try { getTracingController().registerReceiver(ContentApplication.this); } catch (SecurityException e) { // Happens if the process is isolated. Ignore. } // Remove the idle handler. return false; } }); }
public Loopers(Timers timers) { mTimers = timers; if (Looper.myLooper() == Looper.getMainLooper()) { waitWhenIdle = true; } Looper.myQueue().addIdleHandler(new MessageQueue.IdleHandler() { @Override public boolean queueIdle() { Looper l = Looper.myLooper(); if (l != null && shouldQuitLooper()) l.quit(); return true; } }); }
private ReferenceQueue<EngineResource<?>> getReferenceQueue() { if (resourceReferenceQueue == null) { resourceReferenceQueue = new ReferenceQueue<>(); MessageQueue queue = Looper.myQueue(); queue.addIdleHandler(new RefQueueIdleHandler(activeResources, resourceReferenceQueue)); } return resourceReferenceQueue; }
private ReferenceQueue<EngineResource<?>> getReferenceQueue() { if (resourceReferenceQueue == null) { resourceReferenceQueue = new ReferenceQueue<>(); MessageQueue queue = Looper.myQueue(); queue.addIdleHandler(new RefQueueIdleHandler()); } return resourceReferenceQueue; }
private LooperSpy(Looper looper) { try { Field queueField = Looper.class.getDeclaredField("mQueue"); queueField.setAccessible(true); messagesField = MessageQueue.class.getDeclaredField("mMessages"); messagesField.setAccessible(true); nextField = Message.class.getDeclaredField("next"); nextField.setAccessible(true); mainMessageQueue = (MessageQueue) queueField.get(looper); } catch (Exception e) { throw new RuntimeException(e); } }
/** * Replace Android OS's StrictMode.violationsBeingTimed with a custom ArrayList acting as an * observer into violation stack traces. Set up an idle handler so StrictMode violations that * occur on startup are not ignored. */ @SuppressWarnings({"unchecked", "rawtypes" }) @UiThread private static void initializeStrictModeWatch() { try { Field violationsBeingTimedField = StrictMode.class.getDeclaredField("violationsBeingTimed"); violationsBeingTimedField.setAccessible(true); ThreadLocal<ArrayList> violationsBeingTimed = (ThreadLocal<ArrayList>) violationsBeingTimedField.get(null); ArrayList replacementList = new SnoopingArrayList(); violationsBeingTimed.set(replacementList); } catch (Exception e) { // Terminate watch if any exceptions are raised. Log.w(TAG, "Could not initialize StrictMode watch.", e); return; } sNumUploads.set(0); // Delay handling StrictMode violations during initialization until the main loop is idle. Looper.myQueue().addIdleHandler(new MessageQueue.IdleHandler() { @Override public boolean queueIdle() { // Will retry if the native library has not been initialized. if (!LibraryLoader.isInitialized()) return true; // Check again next time if no more cached stack traces to upload, and we have not // reached the max number of uploads for this session. if (sCachedStackTraces.isEmpty()) { // TODO(wnwen): Add UMA count when this happens. // In case of races, continue checking an extra time (equal condition). return sNumUploads.get() <= MAX_UPLOADS_PER_SESSION; } // Since this is the only place we are removing elements, no need for additional // synchronization to ensure it is still non-empty. reportStrictModeViolation(sCachedStackTraces.remove(0)); return true; } }); }
void executeDelayedAfterIdleUnsafe(final Runnable runnable) { // This needs to be called from the main thread. Looper.myQueue().addIdleHandler(new MessageQueue.IdleHandler() { @Override public boolean queueIdle() { backgroundHandler.postDelayed(runnable, delayMillis); return false; } }); }
private void addIdleHandler() { MessageQueue queue = Looper.myQueue(); queue.addIdleHandler(new MessageQueue.IdleHandler() { @Override public boolean queueIdle() { Storage.ensureOSXCompatible(); return false; } }); }
public ACIMessageQueueReplayer(ACInstrumentation instrumentation, MessageQueue queue) { super(instrumentation, queue); mOrder = new LinkedList<MessageInfo>(); mBuffer = new HashMap<MessageInfo, LinkedList<BufferedMessage> >(); mRefCount = new HashMap<MessageInfo, Integer>(); }
public ACIMessageQueueReplayer2(ACInstrumentation instrumentation, MessageQueue queue) { super(instrumentation, queue); mBlockedMessages = new LinkedList<Message>(); mBlockedACISyncRunnables = new LinkedList<Message>(); mOrder = new LinkedList<HashMap<MessageInfo, Integer>>(); mCurrentSet = null; mFireCount = 0; }
public ACIMessageQueueInstrumenter(ACInstrumentation instrumentation, MessageQueue queue) { super(instrumentation, queue); mIO = new AsyncIONode<String>(); mMyPid = android.os.Process.myPid(); mSync = new Object(); mMsgCount = 0; mBuffer = new HashMap<Integer, Message>(); mBusy = false; }
public ACIMessageProxy(ACInstrumentation instrumentation, MessageQueue targetQueue, SynchronousQueue<Object> sync) { mInst = instrumentation; mTargetQueue = targetQueue; mSync = sync; }
public ACIMessageReplayProxy(ACInstrumentation instrumentation, MessageQueue targetQueue, SynchronousQueue<Object> sync) { super(instrumentation, targetQueue, sync); mOrder = new LinkedList<MessageInfo>(); mBuffer = new HashMap<MessageInfo, LinkedList<BufferedMessage> >(); mRefCount = new HashMap<MessageInfo, Integer>(); }
private void executeDelayedAfterIdleUnsafe(final Runnable runnable) { // This needs to be called from the main thread. Looper.myQueue().addIdleHandler(new MessageQueue.IdleHandler() { @Override public boolean queueIdle() { backgroundHandler.postDelayed(runnable, DELAY_MILLIS); return false; } }); }
void waitForIdle(final Retryable retryable, final int failedAttempts) { // This needs to be called from the main thread. Looper.myQueue().addIdleHandler(new MessageQueue.IdleHandler() { @Override public boolean queueIdle() { postToBackgroundWithDelay(retryable, failedAttempts); return false; } }); }