Android_實用技術(3)—— Service簡析(Ⅱ)

来源:http://www.cnblogs.com/pepsimaxin/archive/2016/04/22/5421967.html
-Advertisement-
Play Games

我們在Service(Ⅰ)中瞭解了Service最基本的知識點,今天我們繼續學習Service這個組件(神器)。 先來說一下Service的生命周期:跟Activity相比,Service的生命周期就太簡單了:onCreate()->onStart()->onDestroy() 【主題】:Activ ...


  我們在Service(Ⅰ)中瞭解了Service最基本的知識點,今天我們繼續學習Service這個組件(神器)

  先來說一下Service的生命周期:跟Activity相比,Service的生命周期就太簡單了:onCreate()->onStart()->onDestroy()

----------------------------------------------------------------------------------------------------------------------------------------

  【主題】:Activity與Service之間的Communication

  【問題】:由上貼我們知道,當我們點擊START SERVICE按鈕後,服務的onCreate()和onStartCommand()方法會得到執行,此後Service是一直存在於後臺運行的,Activity無法控制Service中具體的邏輯運行,那麼這樣Activity只相當於起到一個通知的作用,除了告訴Service你可以開始工作了。那麼這樣顯然會分離兩者之間的關聯性,這也不是我們需要的結果!

  【後果】:如果出現以上的問題,那麼在我們平時的項目開發過程中(拿小編做手機開發項目而言),一直存在的Service很有可能會引起功耗的問題,這將嚴重影響手機的運行效率

  【要求】:我們能否將Activity與Service建立一種聯繫,當Activity終結之時,Service也銷毀,也就是有沒有辦法讓Activity和Service能夠“不求同生,但求共死”

  答案是肯定的!這就涉及到Service的另一個重要知識點:綁定解綁

  直接代碼走起,看過來:

(1)MyService.java

public class MyService extends Service{
  
private static final String TAG = "MyService";
  
private DownloadBinder mBinder = new DownloadBinder();       // 定義一個DownloadBinder類
  
class DownloadBinder extends Binder {   // 讓DownloadBinder成為Binder的子類     public void startDownload() {                      // 定義開始下載的方法       Log.d(TAG, "startDownload executed");     }     public int getProgress() {    // 定義一個查看下載進度的方法       Log.d(TAG, "getProgress executed");       return 0;     }   }   @Nullable   @Override   public IBinder onBind(Intent intent) { // onBind()方法,這個方法將在綁定後調用     return mBinder; // 返回IBinder的實例 --> DownloadBinder類的實例   }   ... // 這邊就是之前定義好的onStart()、onStartCommand()、onDestroy()三個方法 }

  (2)接下來,我們在Layout中添加兩個按鈕 BIND SERVICE 和 UNBIND SERVICE

                                  

 

  (3)MainActivity.java

public class MainActivity extends Activity implements View.OnClickListener{
  
private ServiceConnection connection = new ServiceConnection() { // 創建一個ServiceConnection的匿名內部類     @Override     public void onServiceConnected(ComponentName name, IBinder service) { // 重寫onServiceConnected()方法       MyService.DownloadBinder downloadBinder = (MyService.DownloadBinder) service; // 向下轉型取得downloadBinder實例       downloadBinder.startDownload(); // 在Activity中調用Service的方法       downloadBinder.getProgress(); // 在Activity中調用Service的方法     }
    @Override     
public void onServiceDisconnected(ComponentName name) { // 重寫onServiceDisconnected()方法     }   };
  @Override   
protected void onCreate(Bundle savedInstanceState) {     super.onCreate(savedInstanceState);     setContentView(R.layout.activity_main);     Button startService = (Button) super.findViewById(R.id.start_service);     Button stopService = (Button) super.findViewById(R.id.stop_service);     Button bindService = (Button) super.findViewById(R.id.bind_service);     Button unbindService = (Button) super.findViewById(R.id.unbind_service); // 不解釋!!!     startService.setOnClickListener(this);     stopService.setOnClickListener(this);     bindService.setOnClickListener(this);     unbindService.setOnClickListener(this);   }
  @Override   
public void onClick(View v) {     switch (v.getId()) {       case R.id.start_service:         Intent startIntent = new Intent(this, MyService.class);            // START 服務 --> onCreate() --> onStartCommand()         startService(startIntent);         break;       case R.id.stop_service:         Intent stopIntent = new Intent(this, MyService.class); // STOP 服務 --> onDestroy()         stopService(stopIntent);         break;       case R.id.bind_service: // 綁定 --> ?         Intent bindIntent = new Intent(this, MyService.class);         bindService(bindIntent, connection, BIND_AUTO_CREATE);         break;       case R.id.unbind_service: // 解綁 --> ?         unbindService(connection);         break;       default:         break;     }   } }

  (4)我們一起來看一下bindService(bindIntent, connection, BIND_AUTO_CREATE)這個方法:

  bindService接收了3個參數:

    bindIntent:這個參數傳入的就是我們的intent,目的就是調用MyService這個服務。

    connection:這個參數傳入的就是創建好的ServiceConnection的實例,這個參數代表著我們的Activity是要和Service綁定在一起的!

    BIND_AUTO_CREATE:這是一個FLAG,表示在活動和服務進行綁定後自動創建服務。註意!註意!是自動創建服務,也就是說MyService會執行onCreate()方法,但是不會執行onStartCommand()方法!

  (5)好了,說到這邊,我們直接來看看代碼最終的效果吧:

                                                                                     

                       

  小編通過排列組合,對按鈕進行了狂烈的點擊,跟大家一起分享一下上圖中Log的情況,分3種情況:

  (1)START SERVICE + STOP SERVICE:

    當我們先點擊START SERVICE:此時服務啟動,調用onCreat()和onStartCommand()方法;

    當我們後點擊STOP SERVICE:此時,服務被銷毀,調用onDestroy()方法。

  (2)BIND SERVICE + UNBIND SERVICE:

    當我們先點擊BIND SERVICE:此時服務僅僅是創建,並未啟動!所以調用的只是onCreate()方法。此時Activity與Service綁定,會同時調用onBind()方法,此時onServiceConnected()方法會被執行,還記的onBind()方法的返回類型不?我們通過Log可以很明顯發現,Activity調用了服務內部的兩個自定義方法。

    當我們後點擊UNBIND SERVICE:由於服務還未啟動,而BIND SERVICE只是將服務創建好並與活動進行綁定,那麼解綁後,勢必會銷毀這個Service,所以onDestroy()被執行!

  (3)START SERVICE + BIND SERVICE + UNBIND SERVICE + STOP SERVICE

    這麼長的一串字元,小編看的都想吐~~~~

    分析吧:

    1、我們先點擊START SERVICE:onCreat()和onStartCommand()方法被執行,這個就不用多說了;

    2、然後點擊UNBIND SERVICE:這個時候其實活動已經在後臺運行了,我們此時將活動和服務綁定,那麼onCreate()不會再執行,只會執行onServiceConnected()方法,Log裡面打出來看的很清楚。

    3、此時你如果手賤,想STOP SERVICE:那麼恭喜你,毫無反應!為什麼?因為你都沒解綁,你怎麼銷毀?

    4、OK,那我們先解綁,我們點擊UNBIND SERVICE:此時一個奇怪的現象發生了,LOG日誌沒有列印出Destroy()這個方法啊?沒有被執行啊!不是說bind了Service之後,unbind就會銷毀這個服務嗎?這跟我們第(2)條不符合啊。

    5、好吧,我們來看看,其實原因很簡單:我們先start了Service,那麼此時服務已經在後臺運行了,這個時候你bind,讓Service和Activity綁定,其實是沒有什麼意義的。但是既然綁定了,你如果不解綁,那麼Destroy()毫無用武,所以,這種情況和(2)中分析的還是有區別的,此是解綁完後,服務還是舒舒服服的在後臺運行,所以,要想幹掉這個服務,你必須要STOP SERVICE。

    我想你是不是要好好消化一下,很快就可以理解的!

    6、放我們解綁後,再STOP SERVICE:這個時候Service就被槍斃了!

----------------------------------------------------------------------------------------------------------------------------------------

【後記】

  可能小編編寫的帖子過於簡單,也過於基礎了,但是小編始終相信,掌握好基礎是相當重要的,再簡單的知識點也能看出大門道!希望各位Android大神不要嫌棄鄙視啊。

  如果你喜歡,請幫我點個贊,或者可以留言我們一起交流學習,如果文章中有任何錯誤和解釋不到位的,請批評指正!謝謝啦~

 

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • AFN小結 1,AFN概念、原理 2,AFN的封裝使用 3,AFN與其它框架對比 ————————————————————————————————— 1 , AFN的概念原理: AFN的基礎是NSURL,AFN的直接操作對象AFHTTPClient是一個實現了NSCoding和NSCopying協議 ...
  • 最近突然發現我的128G SSD硬碟只剩下可憐的8G多,剩下這麼少的一點空間連Xcode都無法更新。怎麼辦呢?如果升級硬碟的話,第一要花錢,畢竟SSD硬碟還是不便宜,第二是升級比較麻煩,要拆機和遷移系統什麼的特別花時間精力,老了真不願瞎折騰了,只能想辦法能不能清除點空間來。 尋找大塊頭 首先想到的就 ...
  • 一 KVC的基本概念 KVC是Key Value Coding的縮寫,意思是鍵值編碼。 在iOS中,提供了一種方法通過使用屬性的名稱(也就是Key)來間接訪問對象屬性的方法,這個方法可以不通過getter/setter方法來訪問對象的屬性。用KVC可以間接訪問對象屬性的機制。通常我們使用valueF ...
  • // 註意,在有導航欄的情況下,需要在viewDidLoad 中加上 self.automaticallyAdjustsScrollViewInsets = NO;不然會出現圖片下移64的情況 ,scrollView.frame的高度要比圖片的高度大64,不然,圖片顯示不全 源文件在這裡:http: ...
  • Socket小白篇-附加TCP/UDP簡介 1.Socket 什麼是Socket Socket:又稱作是套接字,網路上的兩個程式通過一個雙向的通信連接實現數據的交換,這個連接的一端稱為Socket。 Socket是對TCP/IP的協議的封裝,Socket本身並不是協議,而是一個調用的介面,只有通過S ...
  • 以下內容為原創,歡迎轉載,轉載請註明 來自天天博客: Android MVP&依賴註入&單元測試 註意 :為了區分 中的 與`Android View MVP View Viewer`來表示。 這裡暫時先只討論 和 ,`Model`暫時不去涉及。 1.1 MVP 基礎框架 1.1.1 前提 首先需要 ...
  • 程式的實現需要藉助幾個對象: NSURLRequest:建立了一個請求,可以指定緩存策略、超時時間。和NSURLRequest對應的還有一個NSMutableURLRequest,如果請求定義為NSMutableURLRequest則可以指定請求方法(GET或POST)等信息。 NSURLConne ...
  • 1、場景 1.1 最新三次的提交 分別是:定義了一個變數k = 10 、 定義了一個變數 j = 6 、 定義了一個變數 i = 5 ; 本地倉庫 和 遠程倉庫保持一致 1.2 我添加了一行代碼 如何回退版本到最近的一次,也就是 定義一個變數 k = 10 這個版本 ? 回退的結果 已經回到我們想要 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...