Android WakeLock details, androidwakelock

Source: Internet
Author: User

Android WakeLock details, androidwakelock
Directory

  • Directory
  • Preface
  • Use WakeLock
    • WakeLock levelAndFlags and Use Cases
    • Reference scenarios
  • WakeLock source code analysis
  • Conclusion

Preface

I wonder if you have thought about why one or more QQ messages can light up your screen when your cell phone goes off?
The answer is Android's WakeLock mechanism. This article mainly introduces how to use WakeLock, which cannot be explained in detail. If you are interested, please take a look at the basic usage of WakeLock.

Use WakeLock

Let's take a look at the official Android comments on PowerManager and WakeLock:

  • PowerManager: This class gives you control of the power state of the device.
  • WakeLock: A wake lock is a mechanism to indicate that your application needs to have the device stay on.
WakeLock levelAndFlags and Use Cases
Level CPU retention Keep the screen bright Keep the keyboard on Use Cases
PARTIAL_WAKE_LOCK Yes No No Background services that run for a long time, such as services
SCREEN_DIM_WAKE_LOCK Yes Low brightness No Use FLAG_KEEP_SCREEN_ON unless you have to keep the CPU running until the operation is complete.
SCREEN_BRIGHT_WAKE_LOCK Yes High Brightness No Use FLAG_KEEP_SCREEN_ON unless you have to keep the CPU running until the operation is complete.
FULL_WAKE_LOCK Yes High Brightness Yes Use FLAG_KEEP_SCREEN_ON unless you have to keep the CPU running until the operation is complete.

In addition to the four levels, PowerMager also provides two flags that can be used with the Level.

FLAG Description
ACQUIRE_CAUSES_WAKEUP By default, wake locks does not enable the illumination of the CPU, Screen, or Keyboard immediately (for Screen, it is Dim or Bright, and Keyboard is Bright. after the wake locks is enabled (such as a user activity), you can set the enabled status for the device to continue (SAVE. however, if ACQUIRE_CAUSES_WAKEUP is added, the illumination of Screen or Keyboar can be disabled immediately. A typical application is to immediately light up the screen when receiving an important notification.
ON_AFTER_RELEASE When the wake lock is released, the counter of the activity that currently calls the wake lock will be reset, so the screen will continue to shine for a while.

Note:
The combination of the two flags and PARTIAL_WAKE_LOCK does not work.

Reference scenarios

Write an application to complete the following scenarios:

The Code is as follows:

MainActivity. java

    private void testWakeLock() {        new Thread(new Runnable() {            private void printLog() {                for (int i = 0; i < 10; i ++) {                    Log.e("wangzhengyi", "hello log " + i);                    try {                        Thread.sleep(1);                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                }            }            @Override            public void run() {                Log.e("wangzhengyi", "ready to acquire wakelock!");                try {                    Thread.sleep(10000);                } catch (InterruptedException e) {                    // TODO Auto-generated catch block                    e.printStackTrace();                }                TestWakeLock twl = new TestWakeLock(MainActivity.this);                twl.acquireWakeLock();                printLog();                twl.releaseWakeLock();            }        }).start();    }

TestWakeLock. java

import android.content.Context;import android.os.PowerManager;import android.os.PowerManager.WakeLock;import android.util.Log;public class TestWakeLock {    private WakeLock mWakeLock;    private Context mContext;    public TestWakeLock(Context context) {        this.mContext = context;    }    public void acquireWakeLock() {        if (mWakeLock == null) {            PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);            mWakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.ON_AFTER_RELEASE, "ZHENGYI.WZY");            if (mWakeLock != null) {                mWakeLock.acquire();                Log.e("wangzhengyi", "get powermanager wakelock!");            }        }    }    public void releaseWakeLock() {        if (mWakeLock != null) {            mWakeLock.release();            Log.e("wangzhengyi", "release powermanager wakelock!");        }    }}

AndroidManifest. xml

<uses-permission android:name="android.permission.WAKE_LOCK"/>
WakeLock source code analysis

Don't go deep into the WakeLock source code. How can this be called a detailed explanation !! Next, let's take a look at the source code implementation of WakeLock.

    public WakeLock newWakeLock(int levelAndFlags, String tag) {        validateWakeLockParameters(levelAndFlags, tag);        return new WakeLock(levelAndFlags, tag, mContext.getOpPackageName());    }    public static void validateWakeLockParameters(int levelAndFlags, String tag) {        switch (levelAndFlags & WAKE_LOCK_LEVEL_MASK) {            case PARTIAL_WAKE_LOCK:            case SCREEN_DIM_WAKE_LOCK:            case SCREEN_BRIGHT_WAKE_LOCK:            case FULL_WAKE_LOCK:            case PROXIMITY_SCREEN_OFF_WAKE_LOCK:                break;            default:                throw new IllegalArgumentException("Must specify a valid wake lock level.");        }        if (tag == null) {            throw new IllegalArgumentException("The tag must not be null.");        }    }

As you can see, the newWakeLock method first checks LevelAndFlags and Tag validity, and the code is very simple. You can take a look at it yourself. In fact, the tag cannot be empty, and the Level must use several levels provided by PowerManager.

Next, we will go to the WakeLock constructor. WakeLock is the internal class of PowerManager. Here, I deleted the methods that we do not currently use in the WakeLock class.

    public final class WakeLock {        private final int mFlags;        private final String mTag;        private final String mPackageName;        private final IBinder mToken;        private int mCount;        private boolean mRefCounted = true;        private boolean mHeld;        private final Runnable mReleaser = new Runnable() {            public void run() {                release();            }        };        WakeLock(int flags, String tag, String packageName) {            mFlags = flags;            mTag = tag;            mPackageName = packageName;            mToken = new Binder();        }        /**         * Acquires the wake lock.         * <p>         * Ensures that the device is on at the level requested when the wake         * lock was created.         * </p>         */        public void acquire() {            synchronized (mToken) {                acquireLocked();            }        }        private void acquireLocked() {            if (!mRefCounted || mCount++ == 0) {                // Do this even if the wake lock is already thought to be held                // (mHeld == true)                // because non-reference counted wake locks are not always                // properly released.                // For example, the keyguard's wake lock might be forcibly                // released by the                // power manager without the keyguard knowing. A subsequent call                // to acquire                // should immediately acquire the wake lock once again despite                // never having                // been explicitly released by the keyguard.                mHandler.removeCallbacks(mReleaser);                try {                    mService.acquireWakeLock(mToken, mFlags, mTag, mPackageName, mWorkSource);                } catch (RemoteException e) {                }                mHeld = true;            }        }        /**         * Releases the wake lock.         * <p>         * This method releases your claim to the CPU or screen being on. The         * screen may turn off shortly after you release the wake lock, or it         * may not if there are other wake locks still held.         * </p>         */        public void release() {            release(0);        }        /**         * Releases the wake lock with flags to modify the release behavior.         * <p>         * This method releases your claim to the CPU or screen being on. The         * screen may turn off shortly after you release the wake lock, or it         * may not if there are other wake locks still held.         * </p>         *         * @param flags         *            Combination of flag values to modify the release behavior.         *            Currently only {@link #WAIT_FOR_PROXIMITY_NEGATIVE} is         *            supported.         *         *            {@hide}         */        public void release(int flags) {            synchronized (mToken) {                if (!mRefCounted || --mCount == 0) {                    mHandler.removeCallbacks(mReleaser);                    if (mHeld) {                        try {                            mService.releaseWakeLock(mToken, flags);                        } catch (RemoteException e) {                        }                        mHeld = false;                    }                }                if (mCount < 0) {                    throw new RuntimeException("WakeLock under-locked " + mTag);                }            }        }        /**         * Returns true if the wake lock has been acquired but not yet released.         *         * @return True if the wake lock is held.         */        public boolean isHeld() {            synchronized (mToken) {                return mHeld;            }        }    }

Taking the acquire method as an example, through the source code analysis, we found that the implementation of obtaining WakeLock is carried out through mService:

mService.acquireWakeLock(mToken, mFlags, mTag, mPackageName, mWorkSource);

MService is instantiated in the PowerManager class:

final IPowerManager mService;

The mService instantiation class is/frameworks/base/services/java/com/android/server/power/PowerManagerService. java, and in this class, you finally find that acquireWakeLock is implemented by the native method of the jni layer.

private static native void nativeAcquireSuspendBlocker(String name);

The implementation of this method is in the code/frameworks/base/services/jni/com_android_server_power_PowerManagerService.cpp:

static void nativeAcquireSuspendBlocker(JNIEnv *env, jclass clazz, jstring nameStr) {    ScopedUtfChars name(env, nameStr);    acquire_wake_lock(PARTIAL_WAKE_LOCK, name.c_str());}

This acquire_wake_lock is defined in/hardware/libhardware_legacy/power. c.

acquire_wake_lock(int lock, const char* id){    initialize_fds();//    ALOGI("acquire_wake_lock lock=%d id='%s'\n", lock, id);    if (g_error) return g_error;    int fd;    if (lock == PARTIAL_WAKE_LOCK) {        fd = g_fds[ACQUIRE_PARTIAL_WAKE_LOCK];    }    else {        return EINVAL;    }    return write(fd, id, strlen(id));}

We can see that the real implementation of acquire wake lock is to write a string of characters in the file pointed to by fd.
The file to which fd points is defined as follows:

const char * const NEW_PATHS[] = {    "/sys/power/wake_lock",    "/sys/power/wake_unlock",};
Conclusion

Now, the analysis of Android WakeLock is over. You are welcome to make a brick.

Copyright Disclaimer: This article is an original article by the blogger and cannot be reproduced without the permission of the blogger.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.