Bạn đã bao giờ nghe nói đến service trong Android chưa? Vậy hãy cùng mình tìm hiểu Service trong Android nhé!

Hầu như bất kỳ ứng dụng Android nào cũng có thể cần làm một việc cần nhiều tài nguyên hệ thống. Mình ví dụ như ứng dụng nghe nhạc, chuyển đổi file hay download tệp từ internet…Lúc này bạn cần nghĩ đến việc thực hiện tác vụ đó dưới background thay vì main UI để tránh làm ứng dụng bị treo.

Để thực hiện tác vụ chạy dưới background, bạn có nhiều cách để thực hiện trong Android. Bạn tạo một Thread hoặc Executor trong Activity. Tuy nhiên, nhược điểm của phương pháp này là Thread hay Executor sẽ không tồn tại khi Activity bị destroy.

Một cách khác, đó là sử dụng AsyncTask để xử lý việc này, nhưng nếu ứng dụng của bạn cần Background Thread mà không đính với bất kì Activity nào thì sao? Về bản chất thì AsyncTask vẫn phải tạo trên một Activity nào đó.

Mình ví dụ trường hợp bạn muốn tải một file từ internet và chỉ có cập nhập trạng thái tải trên notification mà không hề có giao diện. Người dùng có thể tắt ứng dụng bất kì lúc nào.

Trong những trường hợp này, Android Services là giải pháp phù hợp nhất.

1. Service trong Android là gì?

Service là một trong 4 thành phần của ứng dụng Android, có thể thực hiện các tác vụ cần nhiều thời gian và không hề có giao diện người dùng(UI). Từ Activity có thể khởi chạy một Service trong Android và sau đó thể tắt ứng dụng để chuyển sang ứng dụng khác mà Service vẫn tiếp tục công việc mà không bị kill.

Tại sao người ta phải tạo ra Service?

Việc xử lý các tác vụ cần nhiều thời gian trên main UI sẽ làm cho ứng dụng bị treo, giảm trải nghiệm người dùng.Vì vậy, khi cần xử lý bất kì tác vụ cần thời gian thì Service trong Android là một trong số ứng viên có thể xem xét.

  • Service không có giao diện người dùng nào và không thể communicate trực tiếp với activity.
  • Một service có thể chạy dưới background vô thời hạn, ngay cả khi ứng dụng bị tắt theo cách thông thường như ấn phím Back, hay Home, hay tắt trong Recent History…
  • Thông thường một service thực hiện một công việc đơn lẻ và tự dừng lại khi nhiệm vụ hoàn thành

Về bản chất thì Service vẫn chạy trên main thread của ứng dụng( mỗi ứng dụng khi chạy, Android sẽ tạo một thread cho ứng dụng đó). Nó không tạo ra Thread riêng độc lập với ứng dụng. Nếu service của bạn mà bị treo, nó có thể khiến ứng dụng bị treo (lỗi ANR). Để khắc phục điều này thì bạn nên tạo một Thread( như AsyncTask) bên trong Service.

2. Các loại service trong Android: Bound và Unbound

#Bound Service trong Android

Với loại service này thì bạn sẽ không gọi start Service bằng startService(), thay vào đó là sẽ gọi phương thức bindService().

Một component(ví dụ như Activity chẳng hạn) gọi Service bằng phương thức bindService(). Activity sẽ liên kết với Service theo dạng client – service. Lúc này Activity có tương tác với Service để gửi và nhận kết quả từ Service.

Ví dụ, mình tạo một Service có nhiệm vụ cập nhật thời tiết. Activity sẽ bind vào Service và yêu cầu Service cập nhật dữ liệu thời tiết bất kì lúc nào, sau đó trả kết quả cho activity hiển thị cho người dùng.

#Unbound Service trong Android

Trường hợp này thì ngược lại với bound service, nghĩa là một Activity có thể khởi chạy service và không quan tâm Service đó chạy như nào, bao giờ thì kết thúc.

Ví dụ, từ activity bắt đầu một service để play bài hát, và service sẻ tiếp tục phát nhạc dưới background vô thời gian kể cả activity đã bị destroy.

3. Vòng đời của Service trong Android

Cũng giống như Activity, Service trong android cũng có vòng đời từ lúc bắt đầu cho đến khi destroy. Để hiểu rõ, các bạn xem hình bên dưới

Vòng đời Android Service

Vòng đời Android Service

onStartCommand()

Hàm này được gọi khi service bắt đầu bằng cách gọi hàm startService(). Khi hàm này thực hiện, service được khởi động và có thể chạy nền background vô thời hạn. Để có thể hủy service thì chỉ có 2 cách:

  1. Bạn tự gọi hàm stopSelf() hoặc stopService().
  2. May rủi chờ đến khi hệ thống Android cần tài nguyên cho ứng dụng khác thì sẽ kill service này .

onBind()

Hàm này chỉ được thực hiện nếu service là bound service. Bạn phải cung cấp một giao diện(interface) mà client sử dụng để giao tiếp với Service bằng cách trả về một IBinder. Hàm này được gọi bất kể khi nào có một thành phần nào đó muốn bind vào service

onCreate()

Đây là hàm được khi service được khởi tạo và chỉ được gọi duy nhất một lần

onDestroy()

Tương tự như Activity thì hàm này được khi service bị hủy(có thể do bạn gọi hàm stopService()hay do hệ thống tự hủy) để giải phóng tài nguyên.

4. Tạo service trong Android

Để các bạn có thể hiểu rõ hơn về cơ chế hoạt động của Service, mình sẽ cùng nhau viết một example sử dụng Service

#Tạo mới Service class

Đầu tiên, tạo một Service có tên là HelloService và override các hàm onStartCommand()onBind()onCreate()và onDestroy()như bên dưới

package com.javatechig.serviceexample;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
public class HelloService extends Service {
    private static final String TAG = "HelloService";
    private boolean isRunning  = false;
    @Override
    public void onCreate() {
        Log.i(TAG, "Service onCreate");
        isRunning = true;
    }
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.i(TAG, "Service onStartCommand");
        //Creating new thread for my service
        //Always write your long running tasks in a separate thread, to avoid ANR
        new Thread(new Runnable() {
            @Override
            public void run() {
                //Your logic that service will perform will be placed here
                //In this example we are just looping and waits for 1000 milliseconds in each loop.
                for (int i = 0; i < 5; i++) {
                    try {
                        Thread.sleep(1000);
                    } catch (Exception e) {
                    }
                    if(isRunning){
                        Log.i(TAG, "Service running");
                    }
                }
                //Stop service once it finishes its task
                stopSelf();
            }
        }).start();
        return Service.START_STICKY;
    }
    @Override
    public IBinder onBind(Intent arg0) {
        Log.i(TAG, "Service onBind");
        return null;
    }
    @Override
    public void onDestroy() {
        isRunning = false;
        Log.i(TAG, "Service onDestroy");
    }
}

#Khai báo Service Manifest

Giống như Activity, Service trong android cũng cần phải khai báo trong Manifest file.

Bạn có thể thiết lập một service chỉ có sẵn cho ứng dụng của bạn bằng cách khai báo thuộc tính android: exportedvà đặt nó thành “false”. Điều này có hiệu quả ngăn các ứng dụng khác bắt đầu service của bạn một cách không kiểm soát.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.javatechig.serviceexample" >
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".HelloActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <!--Service declared in manifest -->
        <service android:name=".HelloService"
            android:exported="false"/>
    </application>
</manifest>

#Bắt đầu một Service Android

Bạn có thể bắt đầu một service từ một Activity hoặc Broadcast Receiver bằng cách gọi hàm startService().

Trong ví dụ này, chúng ta sẽ bắt đầu service bằng cách gọi phương thức startService()khi nút “Start Service

Intent intent = new Intent(this, HelloService.class);
startService(intent);

Và đây là kết quả

Service trong android

Service trong android

Đây chỉ là một ví dụ rất đơn giản để các bạn có thể hình dung cách thức hoạt động của Service.

About the author

Kevin Dang

Hey there! My name is Kevin Dang, I am website, software, mobile app develop, web admin system. Expert living in Hồ Chí Minh (Việt Nam). I am very interested in digital marketing with: SEO, Facebook, Google Ads ... This blog is where I will share the experiences, techniques and knowledge I have learned.