牢補基礎,話說Service那點事

weixin_34148340發表於2018-01-23

一、什麼是Service?

Service通常總是稱之為“後臺服務”.

Service(服務)是一個一種可以在後臺執行長時間執行操作而沒有使用者介面的應用元件。服務可由其他應用元件啟動(如Activity),服務一旦被啟動將在後臺一直執行,即使啟動服務的元件(Activity)已銷燬也不受影響。

此外,元件可以繫結到服務,以與之進行互動,甚至是執行程式間通訊 (IPC)。

其中“後臺”一詞是相對於前臺而言的,具體是指其本身的執行並不依賴於使用者可視的UI介面,因此,從實際業務需求上來理解,Service的適用場景應該具備以下條件:

  • 1.並不依賴於使用者可視的UI介面(當然,這一條其實也不是絕對的,如前臺Service就是與Notification介面結合使用的);

  • 2.具有較長時間的執行特性。

2、Service 是否在 main thread 中執行, service 裡面是否能執行耗時的操作?

  • 預設情況,如果沒有顯示的指 servic 所執行的程式, Service 和 activity 是執行在當前 app 所在進 程的 main thread(UI 主執行緒)裡面。

  • 2、service 裡面不能執行耗時的操作(網路請求,拷貝資料庫,大檔案 ) 特殊情況,可以在清單檔案配置 service 執行所在的程式 ,讓 service 在另外的程式中執行

    <service
    android:name="com.baidu.location.f"
    android:enabled="true"
    android:process=":remote" >
    </service>
    
    複製程式碼

3、Activity 怎麼和 Service 繫結,怎麼在 Activity 中啟動自己對應的Service?

  • Activity 通過 bindService(Intent service, ServiceConnection conn, int flags)跟 Service 進行 繫結,當繫結成功的時候 Service 會將代理物件通過回撥的形式傳給 conn,這樣我們就拿到了 Service 提供的服務代理物件。

  • 在 Activity 中可以通過 startService 和 bindService 方法啟動 Service。一般情況下如果想獲取 Service 的服務物件那麼肯定需要通過 bindService()方法,比如音樂播放器,第三方支付等。

  • 如果僅僅只是為了開啟一個後臺任務那麼可以使用 startService()方法。

5、Service的生命週期考察的也挺多的

Service 有繫結模式和非繫結模式,以及這兩種模式的混合使用方式。不同的使用方法生命週期 方法也不同。

非 綁 定 模 式

當 第 一 次 調 用 startService 的 時 候 執 行 的 方 法 依 次 為 onCreate() 、 onStartCommand(),當 Service 關閉的時候呼叫 onDestory 方法。

繫結模式

第一次 bindService()的時候,執行的方法為 onCreate()、onBind()解除繫結的 時候會執行 onUnbind()、onDestory()。

上面的兩種生命週期是在相對單純的模式下的情形。我們在開發的過程中還必須注意 Service 實 例只會有一個,也就是說如果當前要啟動的 Service 已經存在了那麼就不會再次建立該 Service 當然也不會呼叫 onCreate()方法。

一個 Service可以被多個客戶進行繫結,只有所有的繫結物件都執行了 onBind()方法後該 Service 才會銷燬,不過如果有一個客戶執行了 onStart()方法,那麼這個時候如果所有的 bind 客戶 都執行了 unBind()該 Service 也不會銷燬。

一張圖解決所有

牢補基礎,話說Service那點事

InterService

作為一個老司機,如果連Interservice都沒聽說過,那就有點那個啥了

什麼是 IntentService?有何優點?

我們通常只會使用 Service,可能 IntentService

對大部分同學來說都是第一次聽說。那麼看了 下面的介紹相信你就不再陌生了。如果你還是不瞭解那麼在面試的時候你就坦誠說沒用過或者不瞭解 等。並不是所有的問題都需要回答上來的。

什麼是IntentService?

IntentService 是 Service 的子類,比普通的 Service 增加了額外的功能。

兩個問題:

Service 不會專門啟動一條單獨的程式,Service 與它所在應用位於同一個程式中;

Service 也不是專門一條新執行緒,因此不應該在 Service 中直接處理耗時的任務;

IntentService的特徵

  • 會建立獨立的 worker 執行緒來處理所有的 Intent 請求;

  • 會建立獨立的 worker 執行緒來處理 onHandleIntent()方法實現的程式碼,無需處理多執行緒問題;

  • 所有請求處理完成後,IntentService 會自動停止,無需呼叫 stopSelf()方法停止 Service;

  • 為 Service 的 onBind()提供預設實現,返回 null;

  • 為 Service 的 onStartCommand 提供預設實現,將請求 Intent 新增到佇列中;

public class MyIntentService extends IntentService {
    private String ex = "";
    private Handler mHandler = new Handler() {
        public void handleMessage(android.os.Message msg) {
            Toast.makeText(MyIntentService.this, "-e " + ex, Toast.LENGTH_LONG).show();
        }
    };

    public MyIntentService(){
        super("MyIntentService");
    }
    
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        ex = intent.getStringExtra("start");
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    protected void onHandleIntent(Intent intent) {
    /**
    * 模擬執行耗時任務
    * 該方法是在子執行緒中執行的,因此需要用到 handler 跟主執行緒進行通訊
    */
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    
    mHandler.sendEmptyMessage(0);
    
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    }
}
複製程式碼

5、說說 Activity、Intent、Service 是什麼關係

  • 他們都是 Android 開發中使用頻率最高的類。

  • 其中 Activity 和 Service 都是 Android 四大元件 之一。他倆都是 Context 類的子類 ContextWrapper 的子類,因此他倆可以算是兄弟關係吧。

  • 不過 兄弟倆各有各自的本領,Activity 負責使用者介面的顯示和互動,Service 負責後臺任務的處理。Activity 和 Service 之間可以通過 Intent 傳遞資料,

  • 因此可以把 Intent 看作是通訊使者。

6、Service 和 Activity 在同一個執行緒嗎

對於同一 app 來說預設情況下是在同一個執行緒中的,main Thread (UI Thread)。

7、Service 裡面可以彈吐司麼

可以的。彈吐司有個條件就是得有一個 Context 上下文,而 Service 本身就是 Context 的子類,因此在 Service 裡面彈吐司是完全可以的。比如我們在 Service 中完成下載任務後可以彈一個吐司通知 使用者。

在 service 的生命週期方法 onstartConmand()可不可以執行網路操作?如何在 service 中執行網路操作?

可以直接在 Service 中執行網路操作,在 onStartCommand()方法中可以執行網路操作

Service 有哪些啟動方法,有什麼區別,怎樣停用 Service?

在 Service 的生命週期中,被回撥的方法比 Activity 少一些,只有 onCreate, onStart, onDestroy, onBind 和 onUnbind。

通常有兩種方式啟動一個 Service,他們對 Service 生命週期的影響是不一樣的。

  • 1. 通過 startService Service 會經歷 onCreate 到 onStart,然後處於執行狀態,stopService 的時候呼叫 onDestroy 方法。

    如果是呼叫者自己直接退出而沒有呼叫 stopService 的話,Service 會一直在後臺執行。

  • 2. 通過 bindService Service 會執行 onCreate,然後是呼叫 onBind, 這個時候呼叫者和 Service 繫結在一起。呼叫者退出了,Srevice 就會呼叫 onUnbind->onDestroyed 方法。

    所謂繫結在一起就共存亡了。呼叫者也可以通過呼叫 unbindService 方法來停止服務,這時候 Srevice 就會呼叫 onUnbind->onDestroyed 方法。

需要注意的是如果這幾個方法交織在一起的話,會出現什麼情況呢?

一個原則是 Service 的 onCreate 的方法只會被呼叫一次,就是你無論多少次的 startService 又bindService,Service 只被建立一次。

如果先是 bind 了,那麼 start 的時候就直接執行 Service 的 onStart 方法,如果先是 start,那麼 bind 的時候就直接執行 onBind 方法。

如果 service 執行期間呼叫了 bindService,這時候再呼叫 stopService 的話,service 是不會呼叫 onDestroy 方法的,service 就 stop 不掉了,只能呼叫 UnbindService, service 就會被銷燬

如果一個 service 通過 startService 被 start 之後,多次呼叫 startService 的話,service 會多次調 用 onStart 方法。多次呼叫 stopService 的話,service 只會呼叫一次 onDestroyed 方法。

如果一個 service 通過 bindService 被 start 之後,多次呼叫 bindService 的話,service 只會呼叫 一次 onBind 方法。多次呼叫 unbindService 的話會丟擲異常。

更多文章

NDK專案實戰—高仿360手機助手之解除安裝監聽

高階UI特效仿直播點贊效果—一個優美炫酷的點贊動畫

相信自己,沒有做不到的,只有想不到的。

技術+職場

相關文章