11/08/2018, 22:05

Tìm hiểu service trong android

Service là 1 trong bốn component cơ bản của android(services, activities, content providers, broadcast receivers). Service chạy ẩn ở dưới để thực hiện các thao tác mà không cần tương tác với người dùng. Ví dụ, service có thể mở một bản nhạc trong khi người dùng đang sử dụng ứng dụng khác, hoặc là ...

Service là 1 trong bốn component cơ bản của android(services, activities, content providers, broadcast receivers). Service chạy ẩn ở dưới để thực hiện các thao tác mà không cần tương tác với người dùng. Ví dụ, service có thể mở một bản nhạc trong khi người dùng đang sử dụng ứng dụng khác, hoặc là tải dữ liệu thông qua mạng mà không ảnh hưởng gì đến các hoạt động của người sử dụng. Một service sẽ có 2 loại:

  • Started: Một service được bắt đầu giống như component khác như activities, bắt đầu service bằng cách gọi hàm  startService(). Thông thường, 1 "started service" thực hiện một hành động đơn lẻ và không trả về kết quả cho đối tượng gọi. Ví dụ, nó có thể thực hiện tải hoặc upload file thông qua mạng và khi thực hiện xong thì nó tự đông dừng lại.
  • Bound: Một service được ràng buộc khi các component ràng buộc thông qua gọi hàm bindService(). Service ràng buộc thường là kiểu giao diện client-server, nó cho phép components tương tác với service, gửi yêu cầu, nhận kết quả trả về. Một service ràng buộc có thể chạy với nhiều components ràng buộc đến nó khi chaỵ lần đầu tiên, khi tất cả components của chúng không còn ràng buộc nữa thì service sẽ bị hệ thống hủy. service_lifecycle

Để tạo một service bạn cần tạo một class kế thừa từ class Service hoặc một class con của class Service. Khi cài đặt service, bạn cần cài đặt một số hàm trong vòng đời của service.Dưới đây là một số hàm cần quan trọng cần cài đặt:

  • onStartCommand(): hệ thống sẽ gọi hàm này khi một component khác hoặc một activity yêu cầu bắt đầu service bằng cách gọi hàm startService(). Nếu bạn chỉ muốn sử dụng service kiểu ràng buộc thì không cần phải cài đặt hàm này.
  • onBind(): hệ thống sẽ gọi hàm này khi một component muốn ràng buộc với service bằng cách gọi hàm bindService(). Khi cài đặt hàm này bạn phải cung cấp giao tiếp giữa client và service bằng cách trả về iBinder. Bạn luôn luôn phải cài đặt hàm này, nếu không muốn ràng buộc bạn có thể trả về null.
  • onCreate(): hệ thống gọi hàm này khi lần đầu tiên service chạy trước khi chạy hàm onStartCommand và onBind. Nếu service chạy rồi thì hàm này không được gọi nữa.
  • onDestroy(): hệ thống gọi hàm này khi service không được sử dụng nữa và bạn cần gọi hàm này để giải phóng tài nguyên cần thiết liên quan đến service.

Nếu một component bắt đầu service bằng cách gọi hàm startService() thì nó sẽ chạy cho đến khi chính nó kết thúc với hàm stopSelf() hoặc một component khác gọi hàm stopService()

Nếu một component gọi hàm bindService() để tạo service (lúc này onStartCommand() không được gọi), service chỉ chạy với các component ràng buộc với nó. Khi service không còn ràng buộc từ tất cả các client thì hệ thống sẽ hủy nó.

Hệ thống sẽ buộc phải tắt service trong trường hợp bộ nhớ xuống thấp hoặc nó phải phục hồi lại tài nguyên cho các thao tác mà người dùng đang sử dụng. Nếu service ràng buộc bởi activity mà người dùng đang sử dụng thì sẽ ít bị giải phóng hơn hoặc service chạy dưới foreground sẽ không bao giờ bị giải phóng. Ngoài ra service bắt đầu trong một khoảng thời gian dài cũng có nguy cơ cao bị hệ thống giải phóng.

Khai báo service trong file manifest

Cũng giống như các component khác, bạn cần khai báo tất cả service trong file manifest của ứng dụng. Để khai báo service, bạn thêm thẻ <service> vào trong thẻ <application>. Ví dụ:

<manifest ... >
  ...
  <application ... >
    <service andrdoeoid:name=".ExampleService"/>
    ...
  </application>
</manifest>

Ví dụ: Sau đây là ví dụ sử dụng service để lấy vị trí của người sử dụng.

Đầu tiên tạo project mới. Sau đó chỉnh sửa file MainActivity.java để thêm hai hàm startService và stopService.

package com.example.test;

import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.*;
import android.content.*;

public class MainActivity extends ActionBarActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    //method start service
    public void startService(View view) {
    	startService(new Intent(getBaseContext(), MyService.class));
    }

    //method destroy service
    public void stopService(View view) {
    	stopService(new Intent(getBaseContext(), MyService.class));
    }
}

Tiếp theo, tạo file MyService.java kế thứ từ class Service để thực hiện việc lấy vị trí của người dùng.

package com.example.test;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationManager;
import android.os.IBinder;
import android.widget.Toast;

public class MyService extends Service {

	private LocationManager locationManager;
	private Criteria criteria;

	@Override
	public IBinder onBind(Intent arg0) {
		return null;
	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
	    // Let it continue running until it is stopped.
	    Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();

	    // Get the location manager
	    locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
		// Define the criteria how to select the location provider
		criteria = new Criteria();
		criteria.setAccuracy(Criteria.ACCURACY_COARSE);	//default

		criteria.setCostAllowed(false);

		// the last known location of this provider
		Location location = locationManager.getLastKnownLocation(
				locationManager.getBestProvider(criteria, false));

		Toast.makeText(this, "latitude " + location.getLatitude(), Toast.LENGTH_LONG).show();
		Toast.makeText(this, "longtitude" + location.getLongitude(), Toast.LENGTH_LONG).show();

	    return START_STICKY;
	}

	@Override
	public void onDestroy() {
	    super.onDestroy();
	    Toast.makeText(this, "Service Destroyed", Toast.LENGTH_LONG).show();
	}

}

Tiếp theo là khai báo service trong file manifest.xml

<service android:name=".MyService"></service>

Sau đó là dựng layout gồm 2 button.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_awidth="fill_parent"
 android:layout_height="fill_parent"
 android:orientation="vertical">

 <Button android:id="@+id/btnStartService"
 android:layout_awidth="fill_parent"
 android:layout_height="wrap_content"
 android:text="@string/start_service"
 android:onClick="startService">

 <Button android:id="@+id/btnStopService"
 android:layout_awidth="fill_parent"
 android:layout_height="wrap_content"
 android:text="@string/stop_service"
 android:onClick="stopService" >

</LinearLayout>

service_1service_2service_3

Nguồn tham khảo:

  • http://developer.android.com/guide/components/services.html

  • http://www.tutorialspoint.com/android/android_services.htm

0