Service
Service定義
- Service是可以長時間執行在後臺的,不可見的,沒有介面的元件;
- Service執行在主執行緒中;
- Service可以跨程式呼叫。
為什麼使用Service
- service可以放在獨立的程式中,更安全。
- 使用service可以依賴現有的binder機制不需要在應用層面上處理執行緒同步的繁雜工作。系統可以重新啟動異常死去的service。
- intentservice使用佇列的方式將請求的佇列加入到intent佇列中,然後開啟一個 thread 執行緒,對於非同步的startservice請求,intentservice會處理完第一個之後處理第二個,每一個請求都會在單獨的一個work thread 中處理。不會阻塞應用程式的主執行緒,這就給我們提供了一個思路,每一個耗時的操作都可以使用intentservice中執行
Service基本啟動方式:StartService;bindService
StartService特點
- onCreate只會執行一次,只要呼叫startService,onStartCommand一定會執行
- Service執行在main執行緒中,做耗時操作需要例外開子執行緒
- 通過Intent進行傳參,在onStartCommand接收引數
- 無法獲得Service物件,直接操作Service中的屬性和方法
- 呼叫stopService後,Service會執行onDestory後停止
StartService優缺點
優點:使用簡單,和Activity一樣,只需要幾行程式碼即可啟動Service
缺點:使用startService的方式,無法獲得Service物件,不能直接操作Service中的屬性和方法,只能通過Intent進行傳遞不同引數,重複呼叫startService,觸發onStartCommand。
StartService使用步驟
- 新建類繼承Service
- 重寫onCreate方法(在建立時呼叫的方法,可以用來做資料初始化,Service在沒有停止之前,只會執行一次)
- 實現onBind抽象方法
- 重寫onStartCommand(建立後會呼叫onStartCommand,此方法中可以接收呼叫者傳遞過來的引數,並且可以編寫需要的邏輯程式碼,當重複呼叫Service時,onStartCommand會重複執行)
- 重寫onDestroy方法 (在退出時呼叫,此方法中可以編寫釋放資源的操作)
- 在AndroidManifest檔案中註冊Service(使用標籤註冊)
- 使用startService方法啟動Service
- 使用stopService方法停止Service
StartService程式碼展示
xml檔案
首先要在佈局檔案中設定兩個按鈕,用來啟動和停止Service
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.administrator.sharedapplication.Main3Activity">
<Button
android:id="@+id/start_btn"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="啟動Service"/>
<Button
android:id="@+id/stop_btn"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="停止Service"/>
</LinearLayout>
然後在Activity檔案中對按鈕進行定義、繫結ID、設定監聽和點選事件
package com.example.administrator.sharedapplication;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class Main3Activity extends AppCompatActivity implements View.OnClickListener{
private Button startBtn;
private Button stopBtn;
private Intent intent;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main3);
bindID();
}
private void bindID() {
startBtn=findViewById(R.id.start_btn);
stopBtn=findViewById(R.id.stop_btn);
startBtn.setOnClickListener(this);
stopBtn.setOnClickListener(this);
}
@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.start_btn:
intent = new Intent(this,MyService.class);
startService(intent);//啟動service
break;
case R.id.stop_btn:
stopService(intent);//停止service
break;
default:
break;
}
}
}
最後在新建的類中寫入MyService方式啟動Service的步驟
package com.example.administrator.sharedapplication;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.util.Log;
public class MyService extends Service{
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
Log.e("Service"+Thread.currentThread().getName(),"onCreate...");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e("Service","onStartCommand...");
new Thread(new Runnable() {
@Override
public void run() {
for (int i=0;i<10;i++){
Log.e("Service"+Thread.currentThread().getName(),i+"***");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
Log.e("Service"+Thread.currentThread().getName(),"onDestroy...");
}
}
bindService特點
- onCreate,onBind只會執行一次
- Service執行在main執行緒中,做耗時操作需另開子執行緒
- 可以直接操作Service中的屬性和方法
- 呼叫unbindService後,Service會執行onUnbind,onDestroy方法後停止
bindService優缺點
優點:可以得到Service物件,靈活控制Service內部的屬性和方法。
缺點:使用較為複雜
bindService使用步驟
- 新建類繼承Service
- 實現onBind方法 (這裡不同於startService中實現onBind方法那樣簡單。這裡需要在此方法中返回一個Binder子類物件。)
- 重寫onCreate方法
- 重寫onUnBind方法 (在呼叫unbindService方法解除繫結後,觸發此回撥函式)
- 重寫onDestroy方法
- 在AndroidManifest中註冊Service
- 實現ServiceConnection介面 (這裡是難點)
- 通過bindService繫結Service
- 通過unbindService解綁Service
bindService程式碼展示
在新建的類中寫入TestService 方式啟動Service的步驟
package com.example.administrator.serviceapplication;
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 Administrator on 2018/3/23.
*/
public class TestService extends Service {
private String TAG="TestService";
private Guanjia guanjia = new Guanjia();
class Guanjia extends Binder{
//作用:得到當前Service物件
public TestService getServiceObject(){
return TestService.this;
}
}
public void fly(){
Log.e(TAG,"開飛機");
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
Log.e(TAG,"onBind...");
return guanjia;
}
@Override
public boolean onUnbind(Intent intent) {
Log.e(TAG,"onUnbind...");
return super.onUnbind(intent);
}
@Override
public void onCreate() {
super.onCreate();
Log.e(TAG,"onCreate...");
}
@Override
public void onDestroy() {
super.onDestroy();
Log.e(TAG,"onDestroy...");
}
}
IntentService特點
- IntentService是繼承於Service並處理非同步任務的一個類
- 在IntentService內有一個工作執行緒來處理非同步耗時操作
- 此執行緒無需我們控制和維護
- 當多次啟動時,會以佇列的形式,逐一執行
- 當執行完耗時操作後,此Service會自動停止
IntentService優點
會建立獨立的worker執行緒來處理所有的Intent請求;
會建立獨立的worker執行緒來處理onHandleIntent()方法實現的程式碼,無需處理多執行緒問題;
所有請求處理完成後,IntentService會自動停止,無需呼叫stopSelf()方法停止Service;
多次呼叫時,按佇列的順序逐一執行,每次執行都是從建立到銷燬的全部過程
IntentService和Service區別
- 首先IntentService是繼承自Service;
- Service不是一個單獨的程式,它和應用程式在同一個程式中;
- Service也不是一個執行緒,所以我們要避免在Service中進行耗時的操作;
- IntentService使用佇列的方式將請求的Intent加入佇列,然後開啟了一個Worker Thread(工作執行緒)在處理佇列中的Intent,對於非同步的startService請求,
IntentService會處理完成一個之後在處理第二個,每一個請求都會在一個單獨的Worker Thread中處理,不會阻塞應用程式的主執行緒。
因此,如果我們如果要在Service裡面處理一個耗時的操作,我們可以用IntentService來代替使用。- 使用IntentService 必須首先繼承IntentService並實現onHandleIntent()方法,將耗時的任務放在這個方法執行,其他方面,IntentService和Service一樣。
IntentService使用步驟
- 新建類繼承IntentService
- 實現父類的構造方法
- 重寫onHandleIntent()方法
- 重寫onCreate方法
- 重寫onDesttory方法
- 在AndroidManifest檔案中註冊Service(容易忘記或出錯)
- 在有Content的環境下啟動Service
IntentService程式碼展示
xml檔案
首先要在佈局檔案中設定兩個按鈕,用來開啟和停止IntentService
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.administrator.serviceapplication.Main3Activity">
<Button
android:id="@+id/start_btn"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="開啟IntentService"/>
<Button
android:id="@+id/stop_btn"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="停止IntentService"/>
</LinearLayout>
然後在Activity檔案中對按鈕進行定義、繫結ID、設定監聽和點選事件
package com.example.administrator.serviceapplication;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class Main3Activity extends AppCompatActivity implements View.OnClickListener{
private Button startBtn;
private Button stopBtn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main3);
bindID();
}
private void bindID() {
startBtn=findViewById(R.id.start_btn);
stopBtn=findViewById(R.id.stop_btn);
startBtn.setOnClickListener(this);
stopBtn.setOnClickListener(this);
}
@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.start_btn:
break;
case R.id.stop_btn:
break;
}
}
}
最後在新建的類中寫入MyIntentService 方式啟動Service的步驟
package com.example.administrator.serviceapplication;
import android.app.IntentService;
import android.content.Intent;
import android.support.annotation.Nullable;
import android.util.Log;
/**
* Created by Administrator on 2018/3/23.
*/
public class MyIntentService extends IntentService {
public MyIntentService(String name) {
super(name);
}
public MyIntentService(){
super("");
}
@Override
protected void onHandleIntent(@Nullable Intent intent) {
for (int i=0;i<10;i++){
try {
Log.e("MyIntentService",i+"***");
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
相關文章
- Android ServiceAndroid
- k8s之Service詳解-Service使用K8S
- What is a service mesh?
- Service詳解
- 深入掌握service
- Service Worker初探
- Android Service SecurityAndroid
- Service Locator 模式模式
- 建立windows serviceWindows
- Android Intent ServiceAndroidIntent
- systemd service unit
- 【Azure Bot Service】部署Python ChatBot程式碼到App Service中PythonAPP
- 【應用服務 App Service】App Service 新手資料包APP
- Service呼叫其他Service的private方法, @Transactional會生效嗎(上)
- Android Service生命週期 Service裡面的onStartCommand()方法詳解Android
- 2.4.1 Service Creation in a CDB
- 如何使用 Service 模式模式
- Spring Web Service教程SpringWeb
- Service Mesh 介紹
- Laravel 2.3 Service ProviderLaravelIDE
- Android Service完全解析Android
- Kubernetes Service之ClusterIP
- Kubernetes實驗 Service
- Service啟動流程
- Service銷燬流程
- 認識 Service Worker
- Guide to Database as a Service (DBaaS)GUIIDEDatabase
- Alexa Voice Service 概述
- 清晰地理解Service
- 8.2 Service3
- Service Mesh模式起源模式
- Angular service 詳解Angular
- 【Azure微服務 Service Fabric 】使用az命令建立Service Fabric叢集微服務
- Android Service重啟恢復(Service程式重啟)原理解析Android
- 【Azure App Service】.NET程式碼實驗App Service應用中獲取TLS/SSL 證書 (App Service Windows)APPTLSWindows
- .NET 6學習筆記(2)——通過Worker Service建立Windows Service筆記Windows
- [Javascript] Common axios service for reuseabilityJavaScriptiOS
- dbms_service 永久有效