/** * A thread state. A thread can be in one of the following states: * <ul> * <li>{@link #NEW}
* A thread that has not yet started is in this state. * </li> * <li>{@link #RUNNABLE}
* A thread executing in the Java virtual machine is in this state. * </li> * <li>{@link #BLOCKED}
* A thread that is blocked waiting for a monitor lock * is in this state. * </li> * <li>{@link #WAITING}
* A thread that is waiting indefinitely for another thread to * perform a particular action is in this state. * </li> * <li>{@link #TIMED_WAITING}
* A thread that is waiting for another thread to perform an action * for up to a specified waiting time is in this state. * </li> * <li>{@link #TERMINATED}
* A thread that has exited is in this state. * </li> * </ul> * * <p> * A thread can be in only one state at a given point in time. * These states are virtual machine states which do not reflect * any operating system thread states. * * @since 1.5 * @see #getState */ public enum State { /** * Thread state for a thread which has not yet started. */ NEW, /** * Thread state for a runnable thread. A thread in the runnable * state is executing in the Java virtual machine but it may * be waiting for other resources from the operating system * such as processor. */ RUNNABLE, /** * Thread state for a thread blocked waiting for a monitor lock. * A thread in the blocked state is waiting for a monitor lock * to enter a synchronized block/method or * reenter a synchronized block/method after calling * {@link Object#wait() Object.wait}. */ BLOCKED, /** * Thread state for a waiting thread. * A thread is in the waiting state due to calling one of the * following methods: * <ul> * <li>{@link Object#wait() Object.wait} with no timeout</li> * <li>{@link #join() Thread.join} with no timeout</li> * <li>{@link LockSupport#park() LockSupport.park}</li> * </ul> * * <p>A thread in the waiting state is waiting for another thread to * perform a particular action. * * For example, a thread that has called <tt>Object.wait()</tt> * on an object is waiting for another thread to call * <tt>Object.notify()</tt> or <tt>Object.notifyAll()</tt> on * that object. A thread that has called <tt>Thread.join()</tt> * is waiting for a specified thread to terminate. */ WAITING, /** * Thread state for a waiting thread with a specified waiting time. * A thread is in the timed waiting state due to calling one of * the following methods with a specified positive waiting time: * <ul> * <li>{@link #sleep Thread.sleep}</li> * <li>{@link Object#wait(long) Object.wait} with timeout</li> * <li>{@link #join(long) Thread.join} with timeout</li> * <li>{@link LockSupport#parkNanos LockSupport.parkNanos}</li> * <li>{@link LockSupport#parkUntil LockSupport.parkUntil}</li> * </ul> */ TIMED_WAITING, /** * Thread state for a terminated thread. * The thread has completed execution. */ TERMINATED; }
状态说明
线程在一个给定的时间点只能处于下面其中一种状态:
这些状态是虚拟机状态,并不能反映任何操作系统的线程状态。
NEW:尚未启动的线程处于这个状态。Thread thread = new Thread(new Runnable(){…});处于这个状态。
/** * Creates a new {@code ThreadPoolExecutor} with the given initial * parameters. * * @param corePoolSize the number of threads to keep in the pool, even * if they are idle, unless {@code allowCoreThreadTimeOut} is set * 核心线程数量,线程常驻即使空闲,除非设置了allowCoreThreadTimeOut * @param maximumPoolSize the maximum number of threads to allow in the * pool * 最大线程数,整个线程池的线程数量(核心线程数+普通线程数) * @param keepAliveTime when the number of threads is greater than * the core, this is the maximum time that excess idle threads * will wait for new tasks before terminating. * 超过核心线程数后的空闲线程存活时间 * @param unit the time unit for the {@code keepAliveTime} argument * 时间单位 * @param workQueue the queue to use for holding tasks before they are * executed. This queue will hold only the {@code Runnable} * tasks submitted by the {@code execute} method. * 工作队列:任务被执行前的存放队列 * @param threadFactory the factory to use when the executor * creates a new thread * executor创建线程的工厂 * @param handler the handler to use when execution is blocked * because the thread bounds and queue capacities are reached * ... */ publicThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler)
publicThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler)
//FragmentManager.class privatevoidcheckStateLoss(){ if (this.isStateSaved()) { thrownew IllegalStateException("Can not perform this action after onSaveInstanceState"); } }
@SuppressWarnings("deprecation") voidmoveToState(@NonNull Fragment f, int newState){ FragmentStateManager fragmentStateManager = mFragmentStore.getFragmentStateManager(f.mWho); if (fragmentStateManager == null) { // Ideally, we only call moveToState() on active Fragments. However, // in restoreSaveState() we can call moveToState() on retained Fragments // just to clean them up without them ever being added to mActive. // For these cases, a brand new FragmentStateManager is enough. fragmentStateManager = new FragmentStateManager(mLifecycleCallbacksDispatcher, mFragmentStore, f); // Only allow this FragmentStateManager to go up to CREATED at the most fragmentStateManager.setFragmentManagerState(Fragment.CREATED); } // When inflating an Activity view with a resource instead of using setContentView(), and // that resource adds a fragment using the <fragment> tag (i.e. from layout and in layout), // the fragment will move to the VIEW_CREATED state before the fragment manager // moves to CREATED. So when moving the fragment manager moves to CREATED and the // inflated fragment is already in VIEW_CREATED we need to move new state up from CREATED // to VIEW_CREATED. This avoids accidentally moving the fragment back down to CREATED // which would immediately destroy the Fragment's view. We rely on computeExpectedState() // to pull the state back down if needed. if (f.mFromLayout && f.mInLayout && f.mState == Fragment.VIEW_CREATED) { newState = Math.max(newState, Fragment.VIEW_CREATED); } newState = Math.min(newState, fragmentStateManager.computeExpectedState()); if (f.mState <= newState) { // If we are moving to the same state, we do not need to give up on the animation. if (f.mState < newState && !mExitAnimationCancellationSignals.isEmpty()) { // The fragment is currently being animated... but! Now we // want to move our state back up. Give up on waiting for the // animation and proceed from where we are. cancelExitAnimation(f); } switch (f.mState) { case Fragment.INITIALIZING: if (newState > Fragment.INITIALIZING) { fragmentStateManager.attach(); } // fall through case Fragment.ATTACHED: if (newState > Fragment.ATTACHED) { fragmentStateManager.create(); } // fall through case Fragment.CREATED: // We want to unconditionally run this anytime we do a moveToState that // moves the Fragment above INITIALIZING, including cases such as when // we move from CREATED => CREATED as part of the case fall through above. if (newState > Fragment.INITIALIZING) { fragmentStateManager.ensureInflatedView(); }
if (newState > Fragment.CREATED) { fragmentStateManager.createView(); } // fall through case Fragment.VIEW_CREATED: if (newState > Fragment.VIEW_CREATED) { fragmentStateManager.activityCreated(); } // fall through case Fragment.ACTIVITY_CREATED: if (newState > Fragment.ACTIVITY_CREATED) { fragmentStateManager.start(); } // fall through case Fragment.STARTED: if (newState > Fragment.STARTED) { fragmentStateManager.resume(); } } } elseif (f.mState > newState) { switch (f.mState) { case Fragment.RESUMED: if (newState < Fragment.RESUMED) { fragmentStateManager.pause(); } // fall through case Fragment.STARTED: if (newState < Fragment.STARTED) { fragmentStateManager.stop(); } // fall through case Fragment.ACTIVITY_CREATED: if (newState < Fragment.ACTIVITY_CREATED) { if (isLoggingEnabled(Log.DEBUG)) { Log.d(TAG, "movefrom ACTIVITY_CREATED: " + f); } if (f.mView != null) { // Need to save the current view state if not // done already. if (mHost.onShouldSaveFragmentState(f) && f.mSavedViewState == null) { fragmentStateManager.saveViewState(); } } } // fall through case Fragment.VIEW_CREATED: if (newState < Fragment.VIEW_CREATED) { FragmentAnim.AnimationOrAnimator anim = null; if (f.mView != null && f.mContainer != null) { // Stop any current animations: f.mContainer.endViewTransition(f.mView); f.mView.clearAnimation(); // If parent is being removed, no need to handle child animations. if (!f.isRemovingParent()) { if (mCurState > Fragment.INITIALIZING && !mDestroyed && f.mView.getVisibility() == View.VISIBLE && f.mPostponedAlpha >= 0) { anim = FragmentAnim.loadAnimation(mHost.getContext(), f, false, f.getPopDirection()); } f.mPostponedAlpha = 0; // Robolectric tests do not post the animation like a real device // so we should keep up with the container and view in case the // fragment view is destroyed before we can remove it. ViewGroup container = f.mContainer; View view = f.mView; if (anim != null) { FragmentAnim.animateRemoveFragment(f, anim, mFragmentTransitionCallback); } container.removeView(view); if (FragmentManager.isLoggingEnabled(Log.VERBOSE)) { Log.v(FragmentManager.TAG, "Removing view " + view + " for " + "fragment " + f + " from container " + container); } // If the local container is different from the fragment // container, that means onAnimationEnd was called, onDestroyView // was dispatched and the fragment was already moved to state, so // we should early return here instead of attempting to move to // state again. if (container != f.mContainer) { return; } } } // If a fragment has an exit animation (or transition), do not destroy // its view immediately and set the state after animating if (mExitAnimationCancellationSignals.get(f) == null) { fragmentStateManager.destroyFragmentView(); } } // fall through case Fragment.CREATED: if (newState < Fragment.CREATED) { if (mExitAnimationCancellationSignals.get(f) != null) { // We are waiting for the fragment's view to finish animating away. newState = Fragment.CREATED; } else { fragmentStateManager.destroy(); } } // fall through case Fragment.ATTACHED: if (newState < Fragment.ATTACHED) { fragmentStateManager.detach(); } } }
if (f.mState != newState) { if (isLoggingEnabled(Log.DEBUG)) { Log.d(TAG, "moveToState: Fragment state for " + f + " not updated inline; " + "expected state " + newState + " found " + f.mState); } f.mState = newState; } }
#alias #screen shot phone alias ss=’adb shell screencap /sdcard/screenshot.png && adb pull /sdcard/screenshot.png . && open ./screenshot.png’ alias screenShot=’adb shell screencap /sdcard/screenshot.png && adb pull /sdcard/screenshot.png . && open ./screenshot.png’
#screen record alias sr=’adb shell screenrecord /sdcard/video.mp4’ alias startRecord=’adb shell screenrecord /sdcard/video.mp4’ #control + c to stop alias showRecord=’adb pull /sdcard/video.mp4 . && open ./video.mp4’
#adb input text to phone myinput() { adb shell input text “$1” } alias input=’myinput ‘
#adb stop/start app alias stopApp=’adb shell am force-stop com.alibaba.aliexpresshd’ alias startApp=’adb shell am start “com.alibaba.aliexpresshd/com.alibaba.aliexpresshd.home.ui.MainActivity”‘
#adb debug app alias debugApp=’adb shell am start -D “com.alibaba.aliexpresshd/com.alibaba.aliexpresshd.home.ui.MainActivity”‘
#gradle dependencies() { ./gradlew “$1”:dependencies –configuration debugRuntimeClasspath } alias depen=’dependencies’