[Android căn bản] Bài 10: Service trong Android-Phần 3 Bound Service trong Android.

[Android căn bản] Bài 10: Service trong Android-Phần 3 Bound Service trong Android.

Xin chào các bạn chúng ta lại gặp nhau trong series Android truyền kì rồi. Ở bài trước tôi đã nói với bạn về Unbound service rồi đúng không nào ờ phần này tôi sẽ tiếp tục giới thiệu đến các bạn Bound Service.

Bound Service

Như các bạn đã biết Bound Service là dạng Service ràng buộc nên nó sẽ ràng buộc với một thành phần nào đó và nếu thành phần này chết đi thì nó cũng chết theo luôn và nó hoạt động cũng gần giống với mô hình client-server. Vậy cách sử dụng nó như thế nào.

Cách sử dụng.

Ở ví dụ này tôi sẽ làm một ứng dụng mô phỏng dịch vụ cung cấp thông tin thời tiết ví dụ như bạn chọn Hà Nội thì nó sẽ cho bạn biết là Hà Nội đang nắng hay mưa.

Đầu tiên tôi sẽ thiết kế giao diện như sau:

Giao diện dự báo thời tiết

Giao diện dự báo thời tiết

Cái này khá đơn giản phải không các bạn và hôm nay tôi cũng ngẫu hứng muốn nghịch cái ConstrainLayout của trưởng môn Google nên có thể code layout sẽ hơi lạ tý.

Code activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.tuandc.akinosora.boundservice.MainActivity">
LO

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Location"
        tools:text="Địa điểm"
        tools:layout_constraintTop_creator="1"
        tools:layout_constraintRight_creator="1"
        app:layout_constraintRight_toRightOf="parent"
        android:layout_marginTop="30dp"
        tools:layout_constraintLeft_creator="1"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <EditText
        android:id="@+id/txt_diadiem"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="38dp"
        android:ems="10"
        android:inputType="text"
        android:text="Name"
        app:layout_constraintBottom_toTopOf="@+id/lbl_thoitiet"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        tools:layout_constraintBottom_creator="1"
        tools:layout_constraintLeft_creator="1"
        tools:layout_constraintRight_creator="1" />

    <TextView
        android:id="@+id/lbl_thoitiet"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="37dp"
        android:text="Thời tiết"
        app:layout_constraintBottom_toTopOf="@+id/btn_xem"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        tools:layout_constraintBottom_creator="1"
        tools:layout_constraintLeft_creator="1"
        tools:layout_constraintRight_creator="1"
        tools:text="Thời tiết" />

    <Button
        android:id="@+id/btn_xem"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Thời tiết hôm nay"
        tools:layout_constraintTop_creator="1"
        tools:layout_constraintRight_creator="1"
        tools:layout_constraintBottom_creator="1"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        tools:layout_constraintLeft_creator="1"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>

Vậy là xong phần layout giờ hãy tạo một lớp Service có tên là WeatherService.

Lớp WeatherService ta sẽ viết như sau:

package com.tuandc.akinosora.boundservice;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

public class WeatherService extends Service {
    private static String LOG_TAG = "WeatherService";

    // Tạo một mảng kiểu Map để lưu trữ dữ liệu thời tiết.
    private static final Map<String, String> weatherData = new HashMap<String,String>();

    private final IBinder binder = new LocalWeatherBinder();// Tạo một biến kiểu IBinder

    public class LocalWeatherBinder extends Binder {
    // Tạo một lớp kế thừa lớp Binder
        public WeatherService getService()  {
            // Đây là hàm gọi service nso sẽ trả về WeatherService
            return WeatherService.this;
        }
    }

    public WeatherService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        Log.i(LOG_TAG,"onBind");
        return this.binder;
    }

    @Override
    public void onRebind(Intent intent) {
        Log.i(LOG_TAG, "onRebind");
        super.onRebind(intent);
    }

    @Override
    public boolean onUnbind(Intent intent) {
        Log.i(LOG_TAG, "onUnbind");
        return true;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.i(LOG_TAG, "onDestroy");
    }

    // Trả về thông tin thời tiết ứng với địa điểm của ngày hiện tại.
    public String getWeatherToday(String location) {
        Date now= new Date();
        DateFormat df= new SimpleDateFormat("dd-MM-yyyy");

        String dayString = df.format(now);//Lấy ngày hôm nay
        String keyLocAndDay = location + "$"+ dayString;

        String weather=  weatherData.get(keyLocAndDay);// lấy gia trj thởi tiết
        //Kiểm tra xem weather có null hay không nếu không null trả vẻ weather.
        if(weather != null)  {
            return weather;
        }

        //Tạo một mảng các giá trị về trạng thái thời tiết như nóng, lạnh.....
        String[] weathers = new String[]{"Rainy", "Hot", "Cool", "Warm" ,"Snowy"};

        // Giá trị ngẫu nhiên từ 0 tới 4
        int i= new Random().nextInt(5);

        weather =weathers[i];
        weatherData.put(keyLocAndDay, weather);
        //
        return weather;
    }

}

Và tại mainActivity thì viết như sau:

package com.tuandc.akinosora.boundservice;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {
    private Button Xem;
    private TextView Thoitiet;
    private EditText Diadiem;
    private boolean binded = false;
    private WeatherService weatherService;
    ServiceConnection weatherServiceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            WeatherService.LocalWeatherBinder binder = (WeatherService.LocalWeatherBinder) service;// Binding Service
            weatherService = binder.getService();// Lấy dịch vụ
            binded = true;
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {
// Ham này được chạy khi ngắt kết nối đên Service
            binded = false;
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Xem = (Button) findViewById(R.id.btn_xem);
        Thoitiet = (TextView) findViewById(R.id.lbl_thoitiet);
        Diadiem = (EditText) findViewById(R.id.txt_diadiem);
        Xem.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                String location = Diadiem.getText().toString();

                String weather= weatherService.getWeatherToday(location);// Lấy thông tin thời tiết

                Thoitiet.setText(weather);
            }
        });
    }
    // Khi Activity start.
    @Override
    protected void onStart() {
        super.onStart();

        // Tạo đối tượng Intent cho WeatherService.
        Intent intent = new Intent(this, WeatherService.class);

        // Gọi method bindService(..) để giàng buộc dịch vụ với giao diện.
        this.bindService(intent, weatherServiceConnection, Context.BIND_AUTO_CREATE);
    }

    // Khi Activity ngừng hoạt động.
    @Override
    protected void onStop() {
        super.onStop();
        if (binded) {
            // Hủy giàng buộc kết nối với dịch vụ.
            this.unbindService(weatherServiceConnection);
            binded = false;
        }
    }

}

Xong bạn hãy chạy chương trình và bạn sẽ có được kết quả như sau

Kết quả

Kết quả

Và với loại Bound Service này khi bạn tắt acitivity đi thì dịch vụ cũng sẽ tự hủy.

Như vậy là tôi đã giới thiệu các sử dụng Bound Service với các bạn, bài tiếp theo cũng là phần cuối trong phần Service này là Intent Service, mong các bạn hãy chú ý đón đọc. Xin cảm ơn các bạn đã theo dõi và hẹn gặp lại trong những bài tiếp theo.