1. 程式人生 > >Android service服務詳解

Android service服務詳解

為什麼要寫服務這篇文章

1.被老員工噴了
2.自己犯賤,撿西瓜丟芝麻,該打,555

服務是啥

服務是一個應用程式元件,可以在後臺執行長時間執行,不提供使用者介面。一個應用程式元件可以啟動一個服務,它將繼續在後臺執行,即使使用者切換到另一個應用程式。此外,一個元件可以繫結到一個服務與它互動,多個主鍵也可以繫結同一個服務,甚至執行程序間通訊(IPC)。例如,一個服務可能處理網路通訊、播放音樂、計時操作或與一個內容提供者互動等等,都在後臺執行。

服務的型別

其實可以按照3種方式分
我就只按使用方式分了
1.startService啟動的服務:主要用於啟動一個服務執行後臺任務,不進行通訊。停止服務使用stopService。
2.bindService啟動的服務:方法啟動的服務要進行通訊。停止服務使用unbindService。
3.同時使用startService、bindService 啟動的服務:停止服務應同時使用stopService與unbindService。

服務的生命週期

在這裡插入圖片描述
他們的方法
一、呼叫方法

方法名 作用
startService() 啟動服務
stopService() 關閉服務
bindService() 繫結服務
unbindService() 解綁服務

二、生命方法

方法名 作用
onCreat() 啟動服務
onStartCommand() 開始服務
onBind() 繫結服務
onUnbind() 解綁服務
onDestroy() 銷燬服務

這當中還是有一個onRebind()方法
onRebind()方法被呼叫還有個前提是先前的onUnbind()方法返回值為true

生命週期的呼叫

1)啟動Service服務
單次:startService() —> onCreate() —> onStartCommand()
多次:startService() —> onCreate() —> onStartCommand() —> onStartCommand()
2)停止Service服務
stopService() —> onDestroy()
3)繫結Service服務
bindService() —> onCreate() —> onBind()
4)解綁Service服務
unbindService() —> onUnbind() —> onDestroy()
5)啟動繫結Service服務
startService() —> onCreate() —> onStartCommand() —> bindService() —> onBind()
6)解綁停止Service服務
unbindService() —> onUnbind() —> stopService() —> onDestroy()
7)解綁繫結Service服務
unbindService() —> onUnbind(ture) —> bindService() —> onRebind()

最後附上實驗Demo

MainActivity.class
package com.yuexia.myservice;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class MainActivity extends Activity implements View.OnClickListener{
    private boolean isBound = false;
    private Intent intent;
    private MyBroadcastReceiver mBroadcastReceiver;
    private LocalBroadcastManager localBroadcastManager;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        intent = new Intent(this,TextService.class);
        initView();
    }
    private void initView() {
        Button btn_start=(Button) this.findViewById(R.id.btn_start);
        Button btn_close=(Button) this.findViewById(R.id.btn_close);
        Button btn_bundle=(Button) this.findViewById(R.id.btn_bundle);
        Button btn_unbundle=(Button) this.findViewById(R.id.btn_unbundle);
        btn_start.setOnClickListener(this);
        btn_close.setOnClickListener(this);
        btn_bundle.setOnClickListener(this);
        btn_unbundle.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){

            case R.id.btn_start :
                startService(intent);
                break;

            case R.id.btn_close :
                stopService(intent);
                break;

            case R.id.btn_bundle :
                isBound = bindService(intent, serviceConnection,  Context.BIND_AUTO_CREATE);
                break;
            case R.id.btn_unbundle :
                if (isBound) {
                    unbindService(serviceConnection);
                    isBound = false;
                }
                break;
        }
    }
    // 在Activity中,我們通過ServiceConnection介面來取得建立連線與連線意外丟失的回撥
    ServiceConnection serviceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service){
            // 建立連線
            // 獲取服務的操作物件
            TextService.MyBinder binder = (TextService.MyBinder)service;
            binder.getService();// 獲取到的Service即MyService
        }
        @Override
        public void onServiceDisconnected(ComponentName name) {
            // 連線斷開
        }
    };
}

TextService.class
package com.yuexia.myservice;

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

/**
 * Created by syt98 on 2018/12/20.
 */

public class TextService  extends Service{
    private static final String TAG = "TextService";
    @Override
    public void onCreate() {
        Log.d(TAG, "onCreate: 建立服務");
        super.onCreate();
        // The service is being created
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d(TAG, "onStartCommand: 開始服務");
        return super.onStartCommand(intent, flags, startId);
        // The service is starting, due to a call to startService()
    }
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        Log.d(TAG, "onBind: 繫結服務");
        return new MyBinder();
        // A client is binding to the service with bindService()
    }

    @Override
    public boolean onUnbind(Intent intent) {
        Log.d(TAG, "onUnbind: 解綁服務");
        return super.onUnbind(intent);
        // All clients have unbound with unbindService()
    }

    @Override
    public void onRebind(Intent intent) {
        Log.d(TAG, "onRebind: 從新繫結");
        super.onRebind(intent);
        // A client is binding to the service with bindService(),
        // after onUnbind() has already been called
    }

    @Override
    public void onDestroy() {
        Log.d(TAG, "onDestroy: 銷燬服務");
        super.onDestroy();
        // The service is no longer used and is being destroyed
    }
    // IBinder是遠端物件的基本介面,是為高效能而設計的輕量級遠端呼叫機制的核心部分。但它不僅用於遠端
    // 呼叫,也用於程序內呼叫。這個介面定義了與遠端物件互動的協議。
    // 不要直接實現這個介面,而應該從Binder派生。
    // Binder類已實現了IBinder介面
    class MyBinder extends Binder {
        /**
         * 獲取Service的方法
         * @return 返回PlayerService
         */
        public  TextService getService(){
            return TextService.this;
        }
    }
}

AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.yuexia.myservice">
    
    <uses-permission android:name="android.permission.INTERNET"/>
    
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        
        <service
            android:name=".TextService"
            android:exported="true"
            android:label="TextService" />
            
    </application>
    
</manifest>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    <Button
        android:layout_weight="1"
        android:id="@+id/btn_start"
        android:text="開啟服務"
        android:layout_width="0dp"
        android:layout_height="wrap_content" />
    <Button
        android:layout_weight="1"
        android:id="@+id/btn_close"
        android:text="關閉服務"
        android:layout_width="0dp"
        android:layout_height="wrap_content" />
    <Button
        android:layout_weight="1"
        android:id="@+id/btn_bundle"
        android:text="繫結服務"
        android:layout_width="0dp"
        android:layout_height="wrap_content" />
    <Button
        android:layout_weight="1"
        android:id="@+id/btn_unbundle"
        android:text="解綁服務"
        android:layout_width="0dp"
        android:layout_height="wrap_content" />
</LinearLayout>

本章有很多內容引用了
https://www.jianshu.com/p/1e49e93c3ec8
https://www.jianshu.com/p/cc25fbb5c0b3
關於Android8.0 啟動後臺Service的話請看
https://www.jianshu.com/p/71e16b95988a