iT邦幫忙

DAY 10
1

Android 探索之備忘錄系列 第 10

Android 探索之備忘錄 [Day10-WakefulBroadcastReceiver]

  • 分享至 

  • xImage
  •  

在Day7介紹了wakelock, 讓系統暫時不會進入休眠
而會使用到wakelock的時間點, 往往都是接收到了某個intent
然後藉由intent去開啟service做相對應的任務,
並且在service啟動時取得wakelock, 結束時釋放wakelock

Android SDK針對這個需求提供了一個方便的class: WakefulBroadcastReceiver
這個class繼承原本的BroadcastReceiver, 並且可以幫助我們管理wakelock

使用方式如下:

繼承WakefulBroadcastReceiver, 並且收到intent後使用startWakefulService()
開啟service(這裡使用IntentService)

MyWakefulReceiver.java
public class MyWakefulReceiver extends WakefulBroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        Intent serviceIntent = new Intent(context, MyIntentService.class);
        startWakefulService(context, serviceIntent);
    }
}

SimpleWakefulService.java
public class SimpleWakefulService extends IntentService {
    public SimpleWakefulService() {
        super("SimpleWakefulService");
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        for (int i=0; i<5; i++) {
            Log.i("SimpleWakefulReceiver", "Running service " + (i+1)
                    + "/5 @ " + SystemClock.elapsedRealtime());
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
            }
        }
        Log.i("SimpleWakefulReceiver", "Completed service @ " + SystemClock.elapsedRealtime());
        SimpleWakefulReceiver.completeWakefulIntent(intent);
    }
}

這樣就完全看不到wakelock的管理了吧!

但別忘了因為是WakefulBroadcastReceiver 幫你取得wakelock,
因此還是需要在AndroidManifest.xml宣告wakelock permission

<uses-permission android:name="android.permission.WAKE_LOCK" />

以及宣告這兩個class

<receiver android:name=".MyWakefulReceiver"></receiver>
<service android:name=".SimpleWakefulService"></service>

P.S.
看看WakefulBroadcastReceiver和原本的BroadcastReceiver有甚麼不同:

public abstract class WakefulBroadcastReceiver extends BroadcastReceiver {
    private static final String EXTRA_WAKE_LOCK_ID = "android.support.content.wakelockid";
    private static final SparseArray<PowerManager.WakeLock> mActiveWakeLocks
            = new SparseArray<PowerManager.WakeLock>();
    private static int mNextId = 1;

    public static ComponentName startWakefulService(Context context, Intent intent) {
        synchronized (mActiveWakeLocks) {
            int id = mNextId;
            mNextId++;
            if (mNextId <= 0) {
                mNextId = 1;
            }
            intent.putExtra(EXTRA_WAKE_LOCK_ID, id);
            ComponentName comp = context.startService(intent);
            if (comp == null) {
                return null;
            }
            PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
            PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
                    "wake:" + comp.flattenToShortString());
            wl.setReferenceCounted(false);
            wl.acquire(60*1000);
            mActiveWakeLocks.put(id, wl);
            return comp;
        }
    }

    public static boolean completeWakefulIntent(Intent intent) {
        final int id = intent.getIntExtra(EXTRA_WAKE_LOCK_ID, 0);
        if (id == 0) {
            return false;
        }
        synchronized (mActiveWakeLocks) {
            PowerManager.WakeLock wl = mActiveWakeLocks.get(id);
            if (wl != null) {
                wl.release();
                mActiveWakeLocks.remove(id);
                return true;
            }
            Log.w("WakefulBroadcastReceiver", "No active wake lock id #" + id);
            return true;
        }
    }
}

其實就只是多了startWakefulService(), completeWakefulIntent()這兩個method
startWakefulService負責開啟service並且取得wakelock(注意有時限為60秒)
completeWakefulIntent則是負責釋放wakelock

reference:

https://developer.android.com/reference/android/support/v4/content/WakefulBroadcastReceiver.html
https://android.googlesource.com/platform/frameworks/support/+/refs/heads/master/v4/java/android/support/v4/content/WakefulBroadcastReceiver.java

上一篇
Android 探索之備忘錄 [Day9-JDGUI and DEX2JAR]
下一篇
Android 探索之備忘錄 [Day11-Ping]
系列文
Android 探索之備忘錄30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言