Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發 >> 關於android開發 >> Android實用技術(5)—— Service簡析(Ⅲ)

Android實用技術(5)—— Service簡析(Ⅲ)

編輯:關於android開發

  1、今天我們來分析Service中的一個小技巧:前台服務(Forground Service)

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

  【問題】:我們都知道服務是運行在後台的,如果系統出現內存不足的情況,那麼此時,系統就可能回收後代的服務,那麼我們如何保證服務可以一直運行?

  【解決】:在服務中,有一個前台服務的概念,調用startForground()方法。

  我們看看官網對前台服務及startForeground()的描述:

Android實用技術(5)—— Service簡析(Ⅲ)

  看了官方的解釋後,我們再來看看如何使用,上代碼:

Java代碼
  1. public class MyService extends Service{  
  2.   
  3.   ......  
  4.   
  5.   @Override  
  6.   public void onCreate() {  
  7.     super.onCreate();  
  8.     Intent intent = new Intent(getBaseContext(), MainActivity.class);  
  9.     PendingIntent pi = PendingIntent.getActivity(getBaseContext(), 0 , intent, PendingIntent.FLAG_CANCEL_CURRENT);  
  10.     Notification no = new Notification.Builder(getBaseContext())                // 啟動服務後,在前台添加一個Notification  
  11.         .setWhen(System.currentTimeMillis())  
  12.         .setSmallIcon(R.mipmap.ic_launcher)  
  13.         .setTicker("Create a front desk Service!")  
  14.         .setContentTitle("This is a front desk service")  
  15.         .setContentText("A service skill!!!")  
  16.         .setContentIntent(pi)  
  17.         .setAutoCancel(true)  
  18.         .setDefaults(Notification.DEFAULT_ALL)  
  19.         .build();  
  20.     startForeground(1, no);            
  21.     Log.d(TAG, "onCreate executed");  
  22.   }  
  23. }  

  我們再看一下官方文檔:

Android實用技術(5)—— Service簡析(Ⅲ)

  以上的代碼是在Service的創建中添加了一個Notification,調用startForground()就可以保證:只要服務一直存在,那麼在前台就會一直顯示這個Notification。

  如果我們在onDestroy()中調用stopForground()方法,會銷毀這個Notification,但是Service還是存活的,此時Service就會面臨被System干掉的風險。

  如果直接STOP SERVICE,那麼Notification和Service都會銷毀。

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

  2、接下來,我們再來看一個Service的另外一個小技巧:IntentService

  【問題】:我們知道服務的代碼邏輯是在主線程中執行的,如果我們在主線程中需要執行一些耗時的操作,那麼很有可能出現ANR(程序暫無響應)的狀況。

  這個時候,我們可以采用Android的多線程編程(小編在之前的 AsyncTask 貼中講解過多線程,可以回顧)的方式,我們來看一段代碼:

Java代碼
  1. public class MyService extends Service{  
  2.   @Nullable  
  3.   @Override  
  4.   public IBinder onBind(Intent intent) {  
  5.     return null;  
  6.   }  
  7.   @Override  
  8.   public int onStartCommand(Intent intent, int flags, int startId) {  
  9.     new Thread(new Runnable() {  
  10.       @Override  
  11.       public void run() {  
  12.         // 處理具體的邏輯                     // 開啟一個線程處理耗時操作  
  13.       }  
  14.     }).start();  
  15.     return super.onStartCommand(intent, flags, startId);  
  16.   }  
  17. }  

  現在,服務可以啟動起來了,但是如果不調用StopService()或stopSelf()方法,服務會一直運行,現在我們修改一下代碼:

Java代碼
  1. public class MyService extends Service{  
  2.   @Nullable  
  3.   @Override  
  4.   public IBinder onBind(Intent intent) {  
  5.     return null;  
  6.   }  
  7.   @Override  
  8.   public int onStartCommand(Intent intent, int flags, int startId) {  
  9.     new Thread(new Runnable() {  
  10.       @Override  
  11.       public void run() {  
  12.         // 處理具體的邏輯                     // 開啟一個線程處理耗時操作  
  13.         stopSelf();                         // 讓服務執行完邏輯後自行停止  
  14.       }  
  15.     }).start();  
  16.     return super.onStartCommand(intent, flags, startId);  
  17.   }  
  18. }  

  上面的代碼就是一個標准的Service的書寫形式,主要包含兩個知識點:Thread子線程的創建和stopSelf()方法的調用。

  其實,在一般的使用過程中,一部分程序員很容易忘記以上兩個要點,存在遺忘,那麼有沒有更好的辦法能夠實現上面兩個需求呢?

  【解決】:在Android中,專門提供了一個IntentService類(android.app.IntentService),這個類就能很好的滿足我們的需求!我們直接通過代碼來看:

  (1)新建一個MyIntentService類繼承自IntentService,代碼:

Java代碼
  1. public class MyIntentService extends IntentService{  
  2.   
  3.   public MyIntentService() {  
  4.     super("MyIntentService");  
  5.   }  
  6.   
  7.   @Override  
  8.   protected void onHandleIntent(Intent intent) {  
  9.     Log.d("MyIntentService", "MyIntentServiceThread id is " + Thread.currentThread().getId());  
  10.   }  
  11.   
  12.   @Override  
  13.   public void onDestroy() {  
  14.     super.onDestroy();  
  15.     Log.d("MyIntentService", "onDestroy executed");  
  16.   }  
  17. }  

  以上代碼做了幾件事:

  1、提供了一個無參的構造方法,並且調用了父類的有參構造函數(這個就不需要我說為什麼了吧);

  2、子類實現父類的onHandleIntent()抽象方法,這個方法好就好在,它是一個已經運行在子線程中的方法。也就是說,服務調用了它,那麼執行的邏輯就如同Thread子線程。

  onHandleIntent = Thread().start() + stopSelf()

  3、onHandleIntent()執行完後會銷毀服務?會selfStop()?接著往下看代碼。

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

  (2)在xml文件中,創建一個MyIntentService服務按鈕:

XML/HTML代碼
  1. <Button  
  2.   android:id="@+id/start_intent_service"  
  3.   android:layout_width="match_parent"  
  4.   android:layout_height="wrap_content"  
  5.   android:text="@string/intent_service"/>  

  (3)接下來,修改MainActivity中的代碼:

Java代碼
  1. public class MainActivity extends Activity {  
  2.   
  3.   @Override  
  4.   protected void onCreate(Bundle savedInstanceState) {  
  5.   
  6.     super.onCreate(savedInstanceState);  
  7.     setContentView(R.layout.activity_main);  
  8.     Button startIntentService = (Button) super.findViewById(R.id.start_intent_service);  
  9.     startIntentService.setOnClickListener(new View.OnClickListener() {  
  10.   
  11.       @Override  
  12.       public void onClick(View v) {  
  13.         Log.d("MyIntentService", "MainActivity Thread id is " + Thread.currentThread().getId());            // 查看主線程的id  
  14.         Intent intentService = new Intent(getBaseContext(), MyIntentService.class);                     
  15.         startService(intentService);  
  16.       }  
  17.     });  
  18.   }  
  19. }  

  (4)最後,在AndroidMainfest中注冊服務:

XML/HTML代碼
  1. <service android:name=".MyIntentService" />  

  【結果】:直接看一下代碼執行的效果。

Android實用技術(5)—— Service簡析(Ⅲ)

  從打出的LOG可以看出:

  (1)MyIntentService和MainActivity所在進程的id是不一樣的;

  (2)onHandleIntent()方法在執行完邏輯後確實銷毀了服務,效果等同於stopSelf()。

  從上面的分析可以看出onHandleIntent()方法確實相當的好用!

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved