Sử dụng GCM Network Manager trên Android
Performance của một ứng dụng là điều rất quan trọng, Có nhiều cách để ta có thể tăng điều đó. GCM (Google Cloud Messaging) Network Manager là một cách giúp ta cải thiện performance đối với các các tác vụ có liên quan đến network. GCM Network Manager cho phép các ứng dụng đăng ký các dịch vụ mạng ...
Performance của một ứng dụng là điều rất quan trọng, Có nhiều cách để ta có thể tăng điều đó. GCM (Google Cloud Messaging) Network Manager là một cách giúp ta cải thiện performance đối với các các tác vụ có liên quan đến network. GCM Network Manager cho phép các ứng dụng đăng ký các dịch vụ mạng dựa trên các tiêu chí cụ thể như:
- Schedule one-off vs. periodic tasks: Đăng ký tác vụ thực hiện một lần hoặc lặp lại bằng cách sử dụng API đơn giản.
- Awareness of network activity: Dịch vụ lập lịch của Network Manager sẽ xác định thời gian tối ưu để lên lịch và thực hiện các tác vụ.
- Awareness of device charging state: Một số tác vụ không cần phải được thực hiện ngay lập tức, và nó có thể được thực hiện khi điện thoại đang sạc để giảm thiểu tiêu thụ pin. Đối với những tác vụ như vậy, bạn có thể sác định rằng ứng dụng của bạn phải chờ đợi để chạy cho điến khi điện thoại được sạc.
- Persistence of tasks across boot: GCM Network Manager vẫn lưu giữ trạng thái của tác vụ ngay cả khi thiết bị hay ứng dựng khởi động lại.
- Ease of implementation/refactoring of existing code: Developer có thể dễ dàng làm quen, thực hiện hay override.
Chú ý: Để có thể sử dụng được GCM Network Manager điều mà bạn cần đó là ứng dụng Google Play Servevice phải có sẵn trên thiết bị.
Khai báo trong file Manifest
- Implement GcmTaskService, và khai báo service trong Manifest.
- Khai báo SERVICE_PERMISSION để đảm bảo rằng các ứng dụng khác không thể khởi động dịch vụ của bạn.
- Add intent filters thích hợp. Chi tiết có thể xem thêm trong tài liệu GcmTaskService API: https://developers.google.com/android/reference/com/google/android/gms/gcm/GcmTaskService
<service android:name=".SampleService" android:permission="com.google.android.gms.permission.BIND_NETWORK_TASK_SERVICE" android:exported="true"> <intent-filter> <action android:name="com.google.android.gms.gcm.ACTION_TASK_READY"/> </intent-filter> </service>
Lập lịch cho tác vụ
public class SampleService extends GcmTaskService { @Override public void onInitializeTasks() { super.onInitializeTasks(); } @Override public int onRunTask(TaskParams taskParams) { // thực hiện công việc của service // trả về kết quả if (condition 1) return GcmNetworkManager.RESULT_FAILURE; if (condition 2) return GcmNetworkManager.RESULT_RESCHEDULE; if (condition 3) return GcmNetworkManager.RESULT_SUCCESS; } }
Lập lịch cho tác vụ dựa ta dựa trên nhu cầu của từng ứng dụng, tùy mục đích.
Schedule a one-off task - Lập lịch cho tác vụ chạy một lần
Tác vụ sẽ thực hiện chạy 1 lần khi gọi (kết thúc khi trả về RESULT_SUCCESS hoặc RESULT_FAILURE, được gọi lại khi trả về RESULT_RESCHEDULE)
long startSecs = 0l; // thời điểm bắt đầu thực hiện tác vụ, cho phép thực hiện nhiệm vụ càng sớm càng tốt (0s - ngay lập tức) long endSecs = startSecs + 60l; // khung thời gian tác vụ sẽ thực hiện sau thời điểm bắt đầu - (60s - thực hiện trong khoảng 60s) String tag = "Sample OneoffTask"; // định danh của tác vụ - định danh là duy nhất OneoffTask oneoff = new OneoffTask.Builder() // cài đặt service cần thực hiện .setService(SampleService.class) // cài đặt định danh cho tác vụ - tên định danh không quá 100 ký tự .setTag(tag) // cài đặt khung cửa sổ thời gian để thực hiện tác vụ, xác định thời điểm sớm nhất tác vụ có thể thực hiện, thời điểm chậm nhất tác vụ phải được thực hiện .setExecutionWindow(startSecs, endSecs) // yêu cầu về điều kiện network để có thể thực hiện tác vụ NETWORK_STATE_CONNECTED hoặc NETWORK_STATE_ANY .setRequiredNetwork(com.google.android.gms.gcm.Task.NETWORK_STATE_CONNECTED) // yêu cầu về điều kiện xạc .setRequiresCharging(true) // cho phép tác vụ có thể được ghi đè bởi một tác vụ cùng định danh - mặc định là false .setUpdateCurrent(true) .build(); GcmNetworkManager.getInstance(context).schedule(oneoff);
Chú ý: Bạn có thể set thời gian ngắn để tác vụ có thể được thực hiện nhanh nhất theo ý muốn, nhưng để thực sự tác vụ được thực hiện có thể phải cần đến 30s cho đến 1 phút từ khi tác vụ được start.
Schedule a periodic task- Lập lịch tác vụ chạy định kỳ
Tác vụ sẽ được thực hiện theo định kỳ với thời gian và điều kiện được cài đặt tùy theo mục đích
long periodSecs = 300l; long flexSecs = 5l; String tag = "Sample PeriodicTask"; PeriodicTask periodic = new PeriodicTask.Builder() // cài đặt service cần thực hiện .setService(SampleService.class) // cài đặt chu kỳ tác vụ sẽ được thực hiện trở lại .setPeriod(periodSecs) // cài đặt khoảng thời gian dao động mà tác vụ có thể thực hiện +/- flexSecs .setFlex(flexSecs) // cài đặt định danh cho tác vụ - tên định danh không quá 100 ký tự .setTag(tag) // cài đặt xác định xem tác vụ có được thực hiện trở lại khi thiết bị khởi động lại - mặc định là true (để tác vụ có thể được gọi lại cần thêm quyền permission.RECEIVE_BOOT_COMPLETED, nếu không cài đặt này sẽ được bỏ qua) .setPersisted(true) // yêu cầu về điều kiện network để có thể thực hiện tác vụ NETWORK_STATE_CONNECTED hoặc NETWORK_STATE_ANY .setRequiredNetwork(com.google.android.gms.gcm.Task.NETWORK_STATE_ANY) // yêu cầu về điều kiện xạc .setRequiresCharging(false) // cho phép tác vụ có thể được ghi đè bởi một tác vụ cùng định danh - mặc định là false .setUpdateCurrent(true) .build(); GcmNetworkManager.getInstance(context).schedule(periodic);
Giá trị Flex giúp cho tác vụ được trở lên linh hoạt hơn.
Chú ý:
- Cài đặt giá trị 0 cho setPeriod và setFlex là không hợp lệ
- Khi cài đặt yêu cầu NETWORK_STATE_CONNECTED đối với cả tác vụ chạy một lần hay tác vụ chạy định kỳ, thì khi thiết bị không được kết nối mạng thì tác vụ sẽ không được thực hiện, nó sẽ được thực hiện sau đó khi thiết bị được kết nối mạng trở lại. Và có thể bạn sẽ nhận ra rằng không phải lúc nào khi thiết bị được kết nối mạng trở lại thì tác vụ được pending trước đó sẽ thực hiện ngay, có lúc sẽ phải mất 1 khoảng thời gian để tác vụ có thể được thực hiện trở lại.
Run tasks
Khi lập lịch khởi động dịch vụ, một thread sẽ được tạo và hệ thống gọi vào onRunTask(). Ta có thể override phương thức này để thực hiện công việc mong muốn và giá trị trả về của onRunTask() sẽ xác định những gì mà GCM Network Manager nên làm gì với tác vụ này:
- RESULT_FAILURE: chỉ ra tác vụ thất bại, nhưng không retry.
- RESULT_RESCHEDULE: chỉ ra tác vụ thất bại, và phải được retry với back-off.
- RESULT_SUCCESS: chỉ ra tác vụ đã thành công, và có thể loại bỏ khỏi hàng đợi
Remove task - Loại bỏ tác vụ
Để loại bỏ một tác vụ nào đó tao có thể sử dụng phương thức được cung cấp sẵn của GCM Network Manager
// Hủy bỏ tất cả các tác vụ trước đó đối với lập lịch được cung cấp bởi GcmTaskService GcmNetworkManager.getInstance(context).cancelAllTasks(SampleService.class); // Hủy bỏ một tác vụ được xác định theo định danh GcmNetworkManager.getInstance(context).cancelTask("Sample PeriodicTask", SampleService.class);
Chú ý:
- Khi Google Play Service hoặc ứng dụng được cập nhật mới, tất cả các tác vụ đã được lên lịch trước đó sẽ bị gỡ bỏ. Bạn có thể override phương thức onInitializeTasks() để gọi lại các tác vụ cần thiết.
- Chức năng lập lịch sẽ giữ một PowerManager.WakeLock cho dịch vụ của bạn, nếu tác vụ được thực hiện sau 3 phút mà không trả về kết quả, thì nó được coi là hết thời gian - time out, và wakelock sẽ được release. Việc lặp lại tác vụ lúc này sẽ không còn hiệu lực. Vì vậy, đối với những tác vụ mà cần nhiều thời gian để thực hiện thì bạn có thể sử dụng một số cơ chế khác, API này chỉ phù hợp đối với những tác vụ có thời gian thực hiện tương đối nhanh.