編輯:關於Android編程
?GCM網絡管理器能讓app注冊能執行面向網絡的服務,每個任務只是完成一個工作。它的API能處理這些任務,允許Google Play Services通過系統集中處理這些網絡操作。
?它的API有助於簡化通用的網絡模式,比如說等待網絡連接,網絡重聯和回退等。實事上,GCM網絡管理器通過直觀的API允許開發者更加有精力關注具體的功能實現,少一點精力去關心網絡的問題。
?在介紹GCM網絡管理器之前,我們花點精力來認識一下電池與網絡請求的利害關系,這樣我們才能明白為什麼批處理網絡這麼重要。
?這裡有張Android無線電狀態機的圖表
?這已經很直觀了,我用這張圖表來加固對處理網絡連接的時候喚醒radio是一個巨大消耗的過程的這個概念。本身嘛,調用網絡就是一個對電量的有巨大消耗的操作。
?即使沒有單一的網絡任務可以消耗完電量,但是大量的個別的可以喚醒radio的網絡請求就可以。如果網絡請求彼此分開,然後設備伴隨著radio的打開被喚醒,因為電池的消耗被喚醒的設備不能休眠(就像睡不戳的人一樣)。
?下面的這圖表展示網絡請求來處一個獲取圖片的app,這個app叫PhotoGallery
?好吧,單個請求看起來不是太壞,radio是打開了,但也只是一個請求,是吧?
?下面這張圖顯示的多個網絡調用:
?突然我們有了大量的網絡請求,radio會被每個請求快速喚醒,這樣會很消耗掉電量,而導致極其不好的用戶體驗。
?我們可以批處理網絡請求來節約電量,主要是優化喚醒radio的消耗。如果在radio的生命同期中最消耗的是初始化喚醒階段,那麼我們就只需要通過批處理來只喚醒一次就好了。這個方法適合不立即需要數據的情況,預加載吧。
?下面這個圖表就是反批處理網絡請求的:
?現在這個radio就只被喚醒一次,節約了電量。
?但是有的時候你確實馬上就需要網絡請求,比如你正在打游戲或者發送一個消息。對於這些情況來說,你應該做一個普通的網絡請求,但是,請注意這種類型的網絡請求並不能優化電量。
?既然我們已經看到了用批處理網絡來有效的優化電量的實用性,那現在就讓我們來探索GCM網絡管理在app中的使用。
dependencies { compile 'com.google.android.gms:play-services-gcm:8.1.0' }
?確定僅僅依賴Google Play Services 的GCM的子集,否則你將會引進許多不必要的方法到你的app中。
?接下來。我們必需在AndroidManifest中聲明一個新的Service。
?CustomSerice是一個繼承自GcmTaskService的類,它是處理GCM網絡管理器的核心類。這個Sergice處理任務,這些任務是我們想要完成的任務,用 action ?SERVICE_ACTION_EXECUTE_TASK 來接收GCM網絡管理器的准備執行的通知。
? 接下來,我們創建一個CustomService.java的類來繼承GcmTaskService:
public class CustomService extends GcmTaskService { ... }
? 這個類只要運行可以隨時執行任務,因為我們實現GcmTaskService ,我們必需在CustomService中實現OnRunTask方法:
@Override public int onRunTask(TaskParams taskParams) { Log.i(TAG, "onRunTask"); switch (taskParams.getTag()) { case TAG_TASK_ONEOFF_LOG: Log.i(TAG, TAG_TASK_ONEOFF_LOG); // This is where useful work would go return GcmNetworkManager.RESULT_SUCCESS; case TAG_TASK_PERIODIC_LOG: Log.i(TAG, TAG_TASK_PERIODIC_LOG); // This is where useful work would go return GcmNetworkManager.RESULT_SUCCESS; default: return GcmNetworkManager.RESULT_FAILURE; } }
?我們檢查給的參數來對比TaskParams的tag 來執行相應的代碼,在對應的分支裡面我們可以做復雜的邏輯操作,在demo裡面只是用Log打印了些信息。
?即使我們初始化了GcmTaskService,我們也必需要拿到GcmNetworkManager的引用對象,這個引用會作為剛剛Services執行任務時的hook。
private GcmNetworkManager mGcmNetworkManager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ... mGcmNetworkManager = GcmNetworkManager.getInstance(this); }
?這個GcmNetworkManager對象將被用來執行任務,其中一個方法就是在onCreate中初始化這個成員變量,還有就是當你需要GcmNetworkManager的實例來執行任務時再獲取實例。
?一個單一任務是執行一個任務,這裡有兩種類型:一次性的和定期的。
?我們通過任務窗口提供一個任務,然後調度器決定實際執行時間,因為任務並不是需要立即執行的,所以調度器會幾個網絡請求作為批處理來節約電量。
?調度器會考慮到網絡的可用性,網絡活動和網絡加載。如果都沒有這些問題,調度器通常會處於等待狀態直到指定窗口的結束。
?下面是我怎麼樣執行一次性任務:
Task task = new OneoffTask.Builder() .setService(CustomService.class) .setExecutionWindow(0, 30) .setTag(LogService.TAG_TASK_ONEOFF_LOG) .setUpdateCurrent(false) .setRequiredNetwork(Task.NETWORK_STATE_CONNECTED) .setRequiresCharging(false) .build(); mGcmNetworkManager.schedule(task);
這裡用的是Builder 模式,我們定義所有的參數在我們的任務中:
1. Service 可以控制任務的明確的GcmTaskService,允許我們可以取消
2. Execution window 任務執行的時間段,第一個是下邊界,第二個是上邊界,單位都是s,這個是強制的
3. Tag 用來標記onRunTask 方法中哪個任務是當前執行的。每個tag都應該是唯一的,最大的長度是100.
4. Update Current 這個決定是否應該替換前面一個擁有同一個tag的任務,默認是false,所以新的任務不會覆蓋已經存在的任務
5. Required Network 設置一個指定的網絡狀態支運行,如果網絡狀態是不可用,那麼一直等到網絡可用再執行。
6. Requires Charging 是否應該在設備連接電源的情況下執行任務。
? 全部都設置完成,由GcmNetworkManager的實例來執行。
? 定時任務如下 :
Task task = new PeriodicTask.Builder() .setService(CustomService.class) .setPeriod(30) .setFlex(10) .setTag(LogService.TAG_TASK_PERIODIC_LOG) .setPersisted(true) .build(); mGcmNetworkManager.schedule(task);
? 看起來很像,但是有幾次不一樣
1. Period 指定任務最多每間隔多長時間執行一次,單位是s,默認地,我們不能控制在這個時間段具體哪個時間執行,這個設置是強制要設置的。
2. Flex 指定在靠近結束時間(上個參數設置)內執行任務,如果時間段是30s,flex是10,調度器會在20-30之間執行。
3. Persisted 決定任務是不是應該在重啟之後繼續存在,默認是true,這個對一次性任務不支持,要求獲得”Receive Boot Completed”權限,否則這個設置會被忽略。
? 我們看到了使用GCM網絡管理器api的強大,調度器創建的即簡單又靈活。
看起來很像,但是有幾次不一樣
Period 指定任務最多每間隔多長時間執行一次,單位是s,默認地,我們不能控制在這個時間段具體哪個時間執行,這個設置是強制要設置的。
Flex 指定在靠近結束時間(上個參數設置)內執行任務,如果時間段是30s,flex是10,調度器會在20-30之間執行。
Persisted 決定任務是不是應該在重啟之後繼續存在,默認是true,這個對一次性任務不支持,要求獲得”Receive Boot Completed”
權限,否則這個設置會被忽略。
我們看到了使用GCM網絡管理器api的強大,調度器創建的即簡單又靈活。
? 我們知道了怎麼執行任務,所以我們現在來看看怎麼取消任務,我們不取消正在執行的任務,不過我們可以取消還沒有執行的任務。
? 我們可以用給定的GcmTaskService來取消所有的任務:
mGcmNetworkManager.cancelAllTasks(CustomService.class);
? 我們也可以取消特定tag的任務:
mGcmNetworkManager.cancelTask( CustomService.TAG_TASK_PERIODIC_LOG, CustomService.class );
? 還有一種情況,記住我們不能取消飛行中的任務。
? 我們需要Google Play Services 才能在調度方法中用GCM網絡管理器來處理任務,為了安全的使用Google Play Services,我們需要檢查它是否存在。如下所示:
int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this); if (resultCode == ConnectionResult.SUCCESS) { mGcmNetworkManager.schedule(task); } else { // Deal with this networking task some other way }
? 如果沒有Google Play Services,GcmNetworkManager將會靜默失敗,所以你需要檢查。
? 同樣的,當Google Play Services 或者app更新了,所有的執行任務都會被移除,為了避免失去你當前的執行任務,?GcmNetworkManager將會調用我們GcmTaskService(也就是CustomService)的onInitializeTasks()方法,這個方法可以重新調度所有的任務,這個通常用來執行定時任務:
@Override public void onInitializeTasks() { super.onInitializeTasks(); // Reschedule removed tasks here }
?簡單地重寫了這個方法,在裡面重新執行必要的任務。
?我們一起深入了解了GCM 網絡管理器和如何使用來保護電源,好了,就到這裡吧。
View的Draw時序圖前面幾篇通過對View樹的measure和layout過程分析事,接下來將結合前兩步得到的測量值及在視圖中的位位置,開始進行繪制操作,一步比一步復
本文實例講述了Android編程之圖片顏色處理方法。分享給大家供大家參考,具體如下:你想做到跟美圖秀秀一樣可以處理自己的照片,美化自己的照片嗎?其實你也可以自己做一個這樣
android-library-publish-to-jcenter是一個幫助Android開發者將AAR庫發布到jcenter的項目,android-library-p
明天還要加班,苦逼的程序猿,簡單說說最近遇到的一個問題吧。我在viewpager+fragment學習筆記中簡單介紹過ViewPager+Fragment的用法,其實並不