1. 程式人生 > >《Android那些事》——Demo淺析Service

《Android那些事》——Demo淺析Service

Service概念及用途[概念為轉載]:

A service is an application component that can perform long-running operations in the background and does not provide a user interface。

通常service用來執行一些耗時操作,或者後臺執行不提供使用者互動介面的操作,例如:下載、播放音樂。


Service 中的幾個主要步驟:

1.startService

2.stopService

3.bindService

4.unbindService


以下是Demo:

MainActivity.class

public class MainActivity extends AppCompatActivity implements View.OnClickListener, ServiceConnection {

    private Button start_Service, stop_Service, binder_Service, unbinder_Service, getService;
    private Intent intent;

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

        start_Service = (Button) findViewById(R.id.start);
        stop_Service = (Button) findViewById(R.id.stop);
        binder_Service = (Button) findViewById(R.id.bind);
        unbinder_Service = (Button) findViewById(R.id.unbind);
        getService = (Button) findViewById(R.id.getService);

        start_Service.setOnClickListener(this);
        stop_Service.setOnClickListener(this);
        binder_Service.setOnClickListener(this);
        unbinder_Service.setOnClickListener(this);
        getService.setOnClickListener(this);

        intent = new Intent(MainActivity.this, MyService.class);
    }

    @Override
    //startService() 的呼叫者與服務沒有聯絡,即使呼叫者退出了,服務仍然執行,
    //而bindService() 的呼叫者與服務綁在一起,呼叫者一旦退出了,服務也隨即終止掉。
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.start:
                //每次呼叫startService(Intent)的時候,
                // 都會呼叫該Service物件的onStartCommand(Intent,int,int)方法,
                // 然後在onStartCommand方法中做一些處理。
                //另外如果一個 Service 已經被啟動,其他程式碼再試圖呼叫 startService() 方法,
                // 是不會執行Service中 onCreate() 的,但會重新執行一次 onStart() 。
                startService(intent);
                break;
            case R.id.stop:
                //當呼叫startService()而沒有呼叫bindService() 時,stopService可以直接停止服務
                //當呼叫startService()同時也呼叫了bindService()時,stopService是不能停止在後臺工作的service的,
                //除非呼叫unbindService()或者強制退出客戶端。
                stopService(intent);
                break;
            case R.id.bind:
                //繫結service
                //bindService() 方法的意思是,把這個 Service 和呼叫 Service 的客戶類綁起來,
                // 如果呼叫這個客戶類被銷燬,Service 也會被銷燬。
                //bindService() 方法執行後 Service 會回撥上邊提到的 onBind()方法,
                // 你可以從這裡返回一個實現了 IBind 介面的類,在客戶端操作這個類就能和這個服務通訊了,
                // 比如得到 Service 執行的狀態或其他操作。如果 Service 還沒有執行,
                // 使用這個方法啟動 Service 就會呼叫Service中 onCreate() 方法而不會呼叫 onStart()。
                bindService(intent,this,BIND_AUTO_CREATE);
                break;
            case R.id.unbind:
                //解除繫結
                unbindService(this);
                break;
            case R.id.getService:
                Toast.makeText(MainActivity.this,
                        "當前service的值為:" + myService.getIndex(), Toast.LENGTH_SHORT).show();
                break;
        }
    }

    //如何得到service
    private MyService myService;

    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        //當呼叫bindService方法後就會回撥Activity的onServiceConnected,
        // 在這個方法中會向Activity中傳遞一個IBinder的例項,Acitity需要儲存這個例項
        //在Service中需要建立一個實現IBinder的內部類(這個內部類不一定在Service中實現,但必須在Service中建立它)。
        //在OnBind()方法中需返回一個IBinder例項,不然onServiceConnected方法不會呼叫。
        Toast.makeText(MainActivity.this, "onServiceConnected", Toast.LENGTH_SHORT).show();
        MyService.MyBinder myBinder = (MyService.MyBinder) service;
        myService = myBinder.getMyService();
    }

    @Override
    public void onServiceDisconnected(ComponentName name) {

    }
}

MyService.class

public class MyService extends Service {

    private Timer timer;
    private TimerTask timerTask;
    private int index = 0;

    @Nullable
    //與activity進行繫結
    @Override
    public IBinder onBind(Intent intent) {
        return binder;
    }

    //得到binder物件
    private MyBinder binder = new MyBinder();

    //自定義一個類繼承Binder實現通訊
    public class MyBinder extends Binder {
        //獲得當前Service的狀態
        public MyService getMyService() {
            return MyService.this;
        }
    }

    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        //onStartCommand有4種返回值
        //START_STICKY
        //START_NOT_STICKY
        //START_REDELIVER_INTENT
        //START_STICKY_COMPATIBILITY
        startTimer();
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        stopTimer();
    }

    //開始執行Timer
    public void startTimer() {
        timer = new Timer();
        timerTask = new TimerTask() {
            @Override
            public void run() {
                index++;
                
            }
        };
        timer.schedule(timerTask, 1000, 1000);
    }

    //停止Timer的執行
    public void stopTimer() {
        timer.cancel();
    }

    //實現可讀性
    public int getIndex() {
        return index;
    }
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    android:orientation="vertical"
    tools:context="com.example.administrator.usingservice.MainActivity">


    <Button
        android:id="@+id/start"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="startService" />

    <Button
        android:id="@+id/stop"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="stopService" />

    <Button
        android:id="@+id/bind"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="bindService" />

    <Button
        android:id="@+id/unbind"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="unbindService" />

    <Button
        android:id="@+id/getService"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="getService" />
</LinearLayout>

UI: