Service 使用詳解

極力推薦文章:歡迎收藏
Android 乾貨分享java

閱讀五分鐘,每日十點,和您一塊兒終身學習,這裏是程序員Android

本篇文章主要介紹 Android 開發中的部分知識點,經過閱讀本篇文章,您將收穫如下內容:android

  1. Service 簡介
  2. 四大組件之一,必須在Androidmainfest.xml 中註冊
  3. 啓動模式啓動服務
  4. 綁定模式綁定服務
  5. 前臺服務
  6. AIDL遠程服務

ServiceAndroid四大組件之一(Activity 活動,Service 服務,ContentProvider內容提供者,BroadcastReceiver 廣播),與Activity相比,Activity是運行在前臺,用戶能夠看得見,Service則是運行在後臺,無用戶界面,用戶沒法看到。程序員

Service主要用於組件之間交互(例如:與ActivityContentProviderBroadcastReceiver進行交互)、後臺執行耗時操做等(例以下載文件,播放音樂等,但Service在主線程運行時長不能超過20s,不然會出現ANR,耗時操做通常建議在子線程中進行操做)。微信

1.Service 簡介

在瞭解Service 的生命週期的以前,咱們先了解一下Service的繼承關係,方便咱們更好的瞭解Service網絡

Service 繼承關係以下:

java.lang.Object
   ↳    android.content.Context
       ↳    android.content.ContextWrapper
           ↳    android.app.Service

Service 的兩種啓動模式

Service 有兩種不一樣的啓動模式 ,不一樣的啓動模式對應不一樣生命週期.
Service啓動模式主要分兩種: 1. 啓動模式。 2. 綁定模式。併發

1.啓動模式

此模式經過 startService()方法啓動,此服務能夠在後臺一直運行,不會隨啓動組件的消亡而消亡。只能執行單一操做,沒法返回結果給調用方,經常使用於網絡下載、上傳文件,播放音樂等。app

2.綁定模式

此模式 經過綁定組件(Activity等)調用 bindService() 啓動,此服務隨綁定組件的消亡而解除綁定。ide

若是此時沒有其它經過startService()啓動,則此服務會隨綁定組件的消亡而消亡。
多個組件不只能夠同時綁定一個Service,並且能夠經過進程間通訊(IPC)執行跨進程操做等。學習

3.兩種服務能夠同時運行

啓動模式與綁定模式的服務能夠同時運行,在銷燬服務時,只有兩種模式都不在使用Service時候,才能夠銷燬服務,不然會引發異常。ui

4. 兩種 Service 模式的生命週期

兩種 Service模式的生命週期以下:

兩種 Service 模式生命週期圖

2.四大組件之一,必須在Androidmainfest.xml 中註冊

Service 註冊方法以下:

<manifest ... >
  ...
  <application ... >
      <service android:name=".ServiceMethods" />
      ...
  </application>
</manifest>

注意:

Service如不註冊 ,不會像Activity那樣會致使App CrashService 不註冊 不會報異常信息,可是服務會起不來,如不注意很容易迷惑。

3.啓動模式

經過啓動模式啓動的Service,如不主動關閉,Service會一直在。

啓動模式啓動服務的方法

Intent  mBindIntent = new Intent(ServiceMethods.this, BindServiceMethods.class);
        startService(mStartIntent);

啓動模式啓動服務的生命週期

下面是驗證啓動模式啓動服務的生命週期的方法,詳細生命週期請查看上方Service的生命週期圖。

01-03 17:16:36.147 23789-23789/com.android.program.programandroid I/StartService wjwj:: ----onCreate----
01-03 17:16:36.223 23789-23789/com.android.program.programandroid I/StartService wjwj:: ----onStartCommand----
01-03 17:16:38.174 23789-23789/com.android.program.programandroid I/StartService wjwj:: ----onDestroy----

啓動模式 啓動服務案例

此案例功能:啓動服務,在服務中建立通知

// Service 建立方法
    @Override
    public void onCreate() {
        super.onCreate();
        Log.i(TAG, "----onCreate----");
    }
    // Service  啓動方法
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.i(TAG, "----onStartCommand----");
        // 獲取NotificationManager實例
        notifyManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        // 實例化NotificationCompat.Builder並設置相關屬性
        NotificationCompat.Builder builder = new NotificationCompat.Builder(
                this)
        // 設置小圖標
                .setSmallIcon(R.drawable.ic_launcher)
                .setLargeIcon(
                        BitmapFactory.decodeResource(getResources(),
                                R.drawable.ic_launcher))
                // 設置通知標題
                .setContentTitle("我是經過StartService服務啓動的通知")
                // 設置通知不能自動取消
                .setAutoCancel(false).setOngoing(true)
                // 設置通知時間,默認爲系統發出通知的時間,一般不用設置
                // .setWhen(System.currentTimeMillis())
                // 設置通知內容
                .setContentText("請使用StopService 方法中止服務");

        // 經過builder.build()方法生成Notification對象,併發送通知,id=1
        notifyManager.notify(1, builder.build());

        return super.onStartCommand(intent, flags, startId);
    }
    // Service  銷燬方法
    @Override
    public void onDestroy() {
        Log.i(TAG, "----onDestroy----");
        notifyManager.cancelAll();
        super.onDestroy();
    }

4. 綁定模式啓動綁定服務

綁定模式啓動的服務會隨着綁定逐漸的消亡而解除Service綁定,若是此時Service沒有經過啓動模式啓動,則此服務將會被銷燬。

綁定模式啓動綁定服務的方法

綁定模式,是經過其餘組件啓動的Service

啓動綁定模式服務的方法

// 啓動綁定服務處理方法
    public void BtnStartBindService(View view) {
        // 啓動綁定服務處理方法
        bindService(mBindIntent, serviceConnection, Context.BIND_AUTO_CREATE);
        isBindService = true;
        Toast.makeText(ServiceMethod.this, "啓動 " + mBindCount + " 次綁定服務",
                Toast.LENGTH_SHORT).show();
    }

    
    public void BtnSopBindService(View view) {
        if (isBindService) {
            // 解除綁定服務處理方法
            unbindService(serviceConnection);
            Toast.makeText(ServiceMethod.this, "解除 " + mUnBindCount + " 次綁定服務",
                    Toast.LENGTH_SHORT).show();
            isBindService = false;
        }

    }

綁定服務 隨綁定組件的消亡而消亡

綁定模式 生命週期回調代碼以下:

// Service 建立方法
    @Override
    public void onCreate() {
        super.onCreate();
        Log.i(TAG, "----onCreate----");
    }

    // Service 綁定方法
    @Override
    public IBinder onBind(Intent intent) {
        Log.i(TAG, "----onBind----");

        MyBinder myBinder = new MyBinder();
        return myBinder;
    }

    // Service 解除綁定方法
    @Override
    public boolean onUnbind(Intent intent) {

        Log.i(TAG, "----onUnbind----");
        return super.onUnbind(intent);

    }

    // Service 銷燬方法
    @Override
    public void onDestroy() {
        Log.i(TAG, "----onDestroy----");
        super.onDestroy();
    }

綁定服務的生命週期代碼打印Log信息以下:

01-03 20:32:59.422 13306-13306/com.android.program.programandroid I/BindService wjwj:: ----onCreate----
01-03 20:32:59.423 13306-13306/com.android.program.programandroid I/BindService wjwj:: -----onBind-----
01-03 20:33:09.265 13306-13306/com.android.program.programandroid I/BindService wjwj:: ----onUnbind----
01-03 20:33:09.266 13306-13306/com.android.program.programandroid I/BindService wjwj:: ----onDestroy----

綁定服務案例

功能:獲取綁定模式啓動 綁定服務及解除綁定服務的次數

綁定服務類

package com.android.program.programandroid.component.Service;

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

public class BindServiceMethods extends Service {
    private static final String TAG = "BindService wjwj:";

    public BindServiceMethods() {
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.i(TAG, "----onCreate----");
    }

    @Override
    public IBinder onBind(Intent intent) {
        Log.i(TAG, "----onBind----");

        MyBinder myBinder = new MyBinder();
        return myBinder;
    }


    @Override
    public boolean onUnbind(Intent intent) {

        Log.i(TAG, "----onUnbind----");
        return super.onUnbind(intent);

    }

    @Override
    public void onDestroy() {
        Log.i(TAG, "----onDestroy----");
        super.onDestroy();
    }
}
  • 組件與綁定服務類之間的交互
//    啓動綁定服務處理方法
    public void BtnStartBindService(View view) {

        bindService(mBindIntent, serviceConnection, Context.BIND_AUTO_CREATE);
        isBindService = true;
        Toast.makeText(ServiceMethods.this,"啓動 "+mBindCount+" 次綁定服務",Toast.LENGTH_SHORT).show();
    }

    //    解除綁定服務處理方法
    public void BtnSopBindService(View view) {
        if (isBindService) {
            unbindService(serviceConnection);
            Toast.makeText(ServiceMethods.this,"解除 "+mUnBindCount+" 次綁定服務",Toast.LENGTH_SHORT).show();
            isBindService=false;
        }

    }
  • 組件之間交互所需的 Binder 接口類
/**
* 該類提供 綁定組件與綁定服務提供接口
* */
public class MyBinder extends Binder {
   private int count = 0;

    public int getBindCount() {
        return ++count;
    }
    public int getUnBindCount() {
        return count> 0 ? count-- : 0;
    }
}

5. 提升服務的優先級

服務默認啓動方式是後臺服務,可是能夠經過設置服務爲前臺服務,提升服務的優先級,進而避免手機內存緊張時,服務進程被殺掉。

設置前臺服務的兩種方法

1.設置爲前臺服務

//設置爲前臺服務
startForeground(int, Notification)

2.取消前臺服務
//取消爲前臺服務 stopForeground(true);

startForeground 前臺服務案例

功能:前臺服務綁定通知信息,提升服務進程優先級,不然取消通知信息

package com.android.program.programandroid.component.Service;

import android.app.NotificationManager;
import android.app.Service;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.os.IBinder;
import android.support.v4.app.NotificationCompat;

import com.android.program.programandroid.R;

public class MyStartForcegroundService extends Service {

    public MyStartForcegroundService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }

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

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        if (intent.getAction().equals("start_forceground_service")) {

//        獲取NotificationManager實例
            NotificationManager notifyManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
//        實例化NotificationCompat.Builder並設置相關屬性
            NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
//                設置小圖標
                    .setSmallIcon(R.mipmap.ic_launcher)
                    .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher))
//                設置通知標題
                    .setContentTitle("我是經過startForeground 啓動前臺服務通知")
//                設置通知不能自動取消
                    .setAutoCancel(false)
                    .setOngoing(true)
//                設置通知時間,默認爲系統發出通知的時間,一般不用設置
//                .setWhen(System.currentTimeMillis())
//               設置通知內容
                    .setContentText("請使用stopForeground 方法改成後臺服務");

            //經過builder.build()方法生成Notification對象,併發送通知,id=1
//        設置爲前臺服務
            startForeground(1, builder.build());

        } else if (intent.getAction().equals("stop_forceground_service")) {
            
            stopForeground(true);
        }

        return super.onStartCommand(intent, flags, startId);
    }
}

6. 使用AIDL接口實現遠程綁定

因爲內容較多,後續另開一篇詳細介紹。

至此,本篇已結束,若有不對的地方,歡迎您的建議與指正。同時期待您的關注,感謝您的閱讀,謝謝!

微信關注公衆號: 程序員Android,領福利

相關文章
相關標籤/搜索