天天看點

Android:(本地、可通信的、前台、遠端)Service使用全面介紹

Android:(本地、可通信的、前台、遠端)Service使用全面介紹
Android:(本地、可通信的、前台、遠端)Service使用全面介紹
Android:(本地、可通信的、前台、遠端)Service使用全面介紹

2.具體使用解析

2.1 本地Service

這是最普通、最常用的背景服務Service。

2.1.1 使用步驟

  • 步驟1:建立子類繼承Service類
需重寫父類的onCreate()、onStartCommand()、onDestroy()和onBind()方法
  • 步驟2:建構用于啟動Service的Intent對象
  • 步驟3:調用startService()啟動Service、調用stopService()停止服務
  • 步驟4:在AndroidManifest.xml裡注冊Service

例子:

需重寫父類的onCreate()、onStartCommand()、onDestroy()和onBind()
public class MyService extends Service {


//啟動Service之後,就可以在onCreate()或onStartCommand()方法裡去執行一些具體的邏輯
//由于這裡作Demo用,是以隻列印一些語句
    @Override
    public void onCreate() {
        super.onCreate();
        System.out.println("執行了onCreat()");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        System.out.println("執行了onStartCommand()");
        return super.onStartCommand(intent, flags, startId);


    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        System.out.println("執行了onDestory()");
    }

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

步驟2:在主布局檔案設定兩個Button分别用于啟動和停止Service

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="scut.carson_ho.demo_service.MainActivity">

    <Button
        android:layout_centerInParent="true"
        android:id="@+id/startService"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="啟動服務" />

    <Button
        android:layout_centerInParent="true"
        android:layout_below="@+id/startService"
        android:id="@+id/stopService"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="停止服務" />
</RelativeLayout>      

步驟3:建構Intent對象,并調用startService()啟動Service、stopService停止服務

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private Button startService;
    private Button stopService;

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

        startService = (Button) findViewById(R.id.startService);
        stopService = (Button) findViewById(R.id.stopService);

        startService.setOnClickListener(this);
        startService.setOnClickListener(this);
    }

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

            //點選啟動Service Button
            case R.id.startService:
                //建構啟動服務的Intent對象
                Intent startIntent = new Intent(this, MyService.class);
                //調用startService()方法-傳入Intent對象,以此啟動服務
                startService(startIntent);
                
            //點選停止Service Button
            case R.id.stopService:
                //建構停止服務的Intent對象
                Intent stopIntent = new Intent(this, MyService.class);
                //調用stopService()方法-傳入Intent對象,以此停止服務
                stopService(stopIntent);
                
        }
    }
}      

AndroidManifest.xml

Android:(本地、可通信的、前台、遠端)Service使用全面介紹
Android:(本地、可通信的、前台、遠端)Service使用全面介紹

2.2 可通信的服務Service

  • 上面介紹的Service是最基礎的,但隻能單機使用,即無法與Activity通信
  • 接下來将在上面的基礎用法上,增設“與Activity通信”的功能,即使用綁定Service服務(Binder類、bindService()、onBind()、unbindService()、onUnbind())

2.2.1 執行個體Demo

接下來我将用一個執行個體Demo進行可通信的服務Service說明

  • 步驟1:在建立子類繼承Service類,并建立一個子類繼承自Binder類、寫入與Activity關聯需要的方法、建立執行個體
public class MyService extends Service {

    private MyBinder mBinder = new MyBinder();

    @Override
    public void onCreate() {
        super.onCreate();
        System.out.println("執行了onCreat()");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        System.out.println("執行了onStartCommand()");
        return super.onStartCommand(intent, flags, startId);


    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        System.out.println("執行了onDestory()");
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        System.out.println("執行了onBind()");
        //傳回執行個體
        return mBinder;
    }


    @Override
    public boolean onUnbind(Intent intent) {
        System.out.println("執行了onUnbind()");
        return super.onUnbind(intent);
    }

    //建立一個子類繼承自Binder類
    class MyBinder extends Binder {

        public void service_connect_Activity() {
            System.out.println("Service關聯了Activity,并在Activity執行了Service的方法");

        }
    }
}      

步驟2:在主布局檔案再設定兩個Button分别用于綁定和解綁Service

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="scut.carson_ho.demo_service.MainActivity">

    <Button
        android:layout_centerInParent="true"
        android:id="@+id/startService"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="啟動服務" />

    <Button
        android:layout_centerInParent="true"
        android:layout_below="@+id/startService"
        android:id="@+id/stopService"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="停止服務" />

    <Button
        android:layout_centerInParent="true"
        android:layout_below="@id/stopService"
        android:id="@+id/bindService"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="綁定服務" />

    <Button
        android:layout_centerInParent="true"
        android:layout_below="@id/bindService"
        android:id="@+id/unbindService"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="解綁服務"
        />
</RelativeLayout>      

步驟3:在Activity通過調用MyBinder類中的public方法來實作Activity與Service的聯系

即實作了Activity指揮Service幹什麼Service就去幹什麼的功能

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private Button startService;
    private Button stopService;
    private Button bindService;
    private Button unbindService;

    private MyService.MyBinder myBinder;


    //建立ServiceConnection的匿名類
    private ServiceConnection connection = new ServiceConnection() {

        //重寫onServiceConnected()方法和onServiceDisconnected()方法
        //在Activity與Service建立關聯和解除關聯的時候調用
        @Override
        public void onServiceDisconnected(ComponentName name) {
        }

        //在Activity與Service解除關聯的時候調用
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            //執行個體化Service的内部類myBinder
            //通過向下轉型得到了MyBinder的執行個體
            myBinder = (MyService.MyBinder) service;
            //在Activity調用Service類的方法
            myBinder.service_connect_Activity();
        }
    };

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


        startService = (Button) findViewById(R.id.startService);
        stopService = (Button) findViewById(R.id.stopService);

        startService.setOnClickListener(this);
        stopService.setOnClickListener(this);

        bindService = (Button) findViewById(R.id.bindService);
        unbindService = (Button) findViewById(R.id.unbindService);

        bindService.setOnClickListener(this);
        unbindService.setOnClickListener(this);

    }

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

            //點選啟動Service
            case R.id.startService:
                //建構啟動服務的Intent對象
                Intent startIntent = new Intent(this, MyService.class);
                //調用startService()方法-傳入Intent對象,以此啟動服務
                startService(startIntent);
                break;

            //點選停止Service
            case R.id.stopService:
                //建構停止服務的Intent對象
                Intent stopIntent = new Intent(this, MyService.class);
                //調用stopService()方法-傳入Intent對象,以此停止服務
                stopService(stopIntent);
                break;

            //點選綁定Service
            case R.id.bindService:
                //建構綁定服務的Intent對象
                Intent bindIntent = new Intent(this, MyService.class);
                //調用bindService()方法,以此停止服務

                bindService(bindIntent,connection,BIND_AUTO_CREATE);
                //參數說明
                //第一個參數:Intent對象
                //第二個參數:上面建立的Serviceconnection執行個體
                //第三個參數:标志位
                //這裡傳入BIND_AUTO_CREATE表示在Activity和Service建立關聯後自動建立Service
                //這會使得MyService中的onCreate()方法得到執行,但onStartCommand()方法不會執行
                break;

            //點選解綁Service
            case R.id.unbindService:
                //調用unbindService()解綁服務
                //參數是上面建立的Serviceconnection執行個體
                unbindService(connection);
                break;

                default:
                    break;

        }
    }
}      

2.3 前台Service

前台Service和背景Service(普通)最大的差別就在于:

  • 前台Service在下拉通知欄有顯示通知(如下圖),但背景Service沒有;

TT9$TN8IK1SAPDT%~0IRLS2.png

  • 前台Service優先級較高,不會由于系統記憶體不足而被回收;背景Service優先級較低,當系統出現記憶體不足情況時,很有可能會被回收

2.3.1 具體使用

用法很簡單,隻需要在原有的Service類對onCreate()方法進行稍微修改即可,如下圖:

@Override
    public void onCreate() {
        super.onCreate();
        System.out.println("執行了onCreat()");

        //添加下列代碼将背景Service變成前台Service
        //建構"點選通知後打開MainActivity"的Intent對象
        Intent notificationIntent = new Intent(this,MainActivity.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(this,0,notificationIntent,0);

        //建立Builer對象
        Notification.Builder builer = new Notification.Builder(this);
        builer.setContentTitle("前台服務通知的标題");//設定通知的标題
        builer.setContentText("前台服務通知的内容");//設定通知的内容
        builer.setSmallIcon(R.mipmap.ic_launcher);//設定通知的圖示
        builer.setContentIntent(pendingIntent);//設定點選通知後的操作

        Notification notification = builer.getNotification();//将Builder對象轉變成普通的notification
        startForeground(1, notification);//讓Service變成前台Service,并在系統的狀态欄顯示出來

    }
           

2.3.2 測試結果

運作後,當點選Start Service或Bind Service按鈕,Service就會以前台Service的模式啟動(通知欄上有通知),如下圖

點選啟動服務

2.4 遠端Service

具體請看我寫的另外一篇文章:Android:遠端服務Service(含AIDL & IPC講解)

3. 使用場景

  • 通過上述描述,你應該對Service類型及其使用非常了解;
  • 那麼,我們該什麼時候用哪種類型的Service呢?
  • 各種Service的使用場景請看下圖:
Android:(本地、可通信的、前台、遠端)Service使用全面介紹
Android:(本地、可通信的、前台、遠端)Service使用全面介紹