Service面試知識小結

本博客是對Service基本面試知識的一個小結,該博客複製參考了Hensen_,感謝原文博主的分享,在前人的基礎上做了補充,方便後期知識的回顧。

1、Service是什麼?

Service是四大組件之一,它可以在後臺執行長時間運行操作而沒有用戶界面的應用組件。

2、Service和Thread的區別

  • Service是安卓中系統的組件,它運行在獨立進程的主線程中,不可以執行耗時操作。Thread是程序執行的最小單元,分配CPU的基本單位,可以開啓子線程執行耗時操作。

  • Service在不同Activity中可以獲取自身實例,可以方便的對Service進行操作。Thread在不同的Activity中難以獲取自身實例,如果Activity被銷燬,Thread實例就很難再獲取得到。

  • Service通常應用於後臺數據統計、播放音樂、版本更新下載等。

3、Service啓動方式

  • startService

    1.定義一個類繼承Service.
    
    2.在Manifest.xml文件中配置該Service。
    
    3.使用Context的startService(intent)方法開啓服務。
    
    4.使用Context的stopService(intent)方法關閉服務。
    5.該啓動方式,app殺死、Activity銷燬沒有任何影響,服務不會停止銷燬。
    
  • bindService

    1.創建BindService服務端,繼承Service並在類中,創建一個實現IBinder接口的實例對象,並提供公共方法給客戶端(Activity)調用。
    
    2.從onBinder()回調方法返回該Binder實例。
    
    3.在客戶端(Activity)中,從onServiceConnection()回調方法參數中接收Binder,通過Binder對象即可訪問Service內部的數據。
    
    4.在manifests中註冊BindService, 在客戶端中調用  bindService()方法開啓綁定Service,調用 unbindService()方法註銷解綁Service。
    
    5. 該啓動方式依賴於客戶端生命週期,當客戶端Activity銷燬時,沒有調用unbindService()方法,Service也會停止銷燬。
    

服務端BindService代碼:

package com.example.ling.myreview.service;

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;

public class BindService extends Service {
    private final String TAG = getClass().getName();
    private final MyBinder mBinder = new MyBinder();
    private final String mMessage = "我是Service的數據哈";

    // 通過繼承Binder來實現IBinder接口
    // service允許客戶端通過IBinder對象來訪問Service內部數據
    public class MyBinder extends Binder {
        // 獲取Service的mMessage數據
        public String getServiceMessage() {
            return mMessage;
        }
    }

    // service被創建時回調
    @Override
    public void onCreate() {
        super.onCreate();
        Log.d(TAG, "Service is create");
    }

    // service被綁定時回調
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        Log.d(TAG, "Service is bind");
        return mBinder;
    }

    // service 被啓動時回調
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d(TAG, "Service is start");
        return super.onStartCommand(intent, flags, startId);
    }

    // service 被解綁時回調
    @Override
    public boolean onUnbind(Intent intent) {
        Log.d(TAG, "Service is unbind");
        return super.onUnbind(intent);
    }

    // service 被銷燬時回調
    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "Service is destroy");
    }
}

客戶端 BindServiceActivity 代碼:

package com.example.ling.myreview.service;

import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import com.example.ling.myreview.R;

public class BindServiceActivity extends AppCompatActivity {
    private final String TAG = getClass().getName();
    private BindService.MyBinder mBinder = null;
    private boolean mIsBind = false;


    // Activity 與 Service 連接狀態監聽類
    private ServiceConnection mConn = new ServiceConnection() {
        // 連接成功回調方法
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            // 獲取Service onBind方法返回的MyBinder對象。
            mBinder = (BindService.MyBinder) service;
        }

        // 連接失敗出現異常的回調方法
        @Override
        public void onServiceDisconnected(ComponentName name) {
            mBinder = null;
        }
    };

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

    // 綁定服務按鈕點擊事件
    public void onClickBindService(View view) {
        Intent intent = new Intent(this, BindService.class);
        bindService(intent, mConn, BIND_AUTO_CREATE);
        mIsBind = true;
    }

    // 解綁服務按鈕點擊事件
    public void onClickUnbindService(View view) {
        if (mIsBind) {
            unbindService(mConn);
            mIsBind = false;
        }
    }

    // 獲取Service內部數據按鈕點擊事件
    public void onClickGetServiceData(View view) {
        // 通過MyBinder獲取Service內部數據。
        if (mBinder != null) {
            final String message = mBinder.getServiceMessage();
            Log.d(TAG, "獲取Service的內部數據:message = " + message);
        }
    }
}

清單文件配置:

        <service android:name=".service.BindService" />
        <activity android:name=".service.BindServiceActivity" />

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"
    android:orientation="vertical"
    >

    <Button
        android:id="@+id/button1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="onClickBindService"
        android:text="綁定服務"
        />
    <Button
        android:id="@+id/button2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="onClickUnbindService"
        android:text="解綁服務"
        />
    <Button
        android:id="@+id/button3"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="onClickGetServiceData"
        android:text="獲取Service裏的數據"
        android:textAllCaps="false"
        />

</LinearLayout>

打印日誌結果:
綁定服務日誌

4、onStartCommand()返回值int值的區別

博文Service中onStartCommand方法返回值的探索

  • START_STICKY_COMPATIBILITY,START_STICKY的兼容版本,但不保證服務被終止後一定能重啓。

  • START_STICKY, 程序被異常kill後(服務被重啓了,但intent對象被清除了) 。

  • START_NOT_STICKY,程序被異常kill後(服務沒有被重建) 。

  • START_REDELIVER_INTENT,程序被異常kill後(服務被重啓了,並保留了intent對象) 。

4、Service生命週期

startService

  • onCreate():創建時回調。
  • onStartCommand():啓動時回調,每startService()一次,都會回調一次。
  • onDestroy():關閉銷燬時回調。

bindService

  • onCreate():創建時回調。
  • onBind():綁定時回調,多次調用bindService()只會回調一次。
  • onUnbind():接除綁定時回調。
  • onDestroy():關閉銷燬時回調。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章