Service使用總結 與sdk部分翻譯

 

 

1. Service SDK翻譯

自己的翻譯 英語不好 硬着頭皮翻譯了些:

A Service is an application component that can perform long-running operations in the background and does not provide a user interface. Another application component can start a service and it will continue to run in the background even if the user switches to another application. Additionally, a component can bind to a service to interact with it and even perform interprocess communication (IPC). For example, a service might handle network transactions, play music, perform file I/O, or interact with a content provider, all from the background.

Service服務 是一種能夠在後臺執行長時間任務 但不提供UI的應用組件

其他的應用組件可開始一個Service服務,是它在後臺繼續運行 甚至是進程間通信IPC

比如 一個Service可以處理網絡傳輸,音樂播放,文件讀寫操作,或是使用content provider,這些都是後臺運行的

 

 

 

Service

This is the base class for all services. When you extend this class, it's important that you create a new thread in which to do all the service's work, because the service uses your application's main thread, by default, which could slow the performance of any activity your application is running.、

 

IntentService

This is a subclass of Service that uses a worker thread to handle all start requests, one at a time. This is the best option if you don't require that your service handle multiple requests simultaneously. All you need to do is implement onHandleIntent(), which receives the intent for each start request so you can do the background work.

 

Service

這是所有Service的父類,當你繼承它時,一定要建立新的線程去執行Service的任務,因爲這個service將會使用你應用的主線程,默認時他會拖慢你應用中正在運行的所有activity。

IntentService

這是一個Service的子類,它使用一個工作線程來一次一個的處理所有開始的請求。這是最好的選擇,如果你不要求您的服務同時處理多個請求。你所要做的只是實現onHandleIntent()方法,用來接收處理每個intent請求,這些都是後臺運行的。

 

 

Because most started services don't need to handle multiple requests simultaneously (which can actually be a dangerous multi-threading scenario), it's probably best if you implement your service using the IntentService class.

因爲大部分開始的服務不需要同時處理多個請求(實際上這是一個危險的多線程的情況)。所以使用IntentService類實現服務可能是最好的方式了。

 

 

 

後面是摘自他人的 ,覺得不錯轉在這裏,多多學習

 

2. Service的調用 
(1)Context.startService():Service會經歷onCreate -> onStart(如果Service還沒有運行,則android先調用onCreate()然後調用onStart();如果Service已經運行,則只調用onStart(),所以一個Service的onStart方法可能會重複調用多次 );stopService的時候直接onDestroy,如果是調用者自己直接退出而沒有調用stopService的話,Service會一直在後臺運行。該Service的調用者再啓動起來後可以通過stopService關閉Service。 注意,多次調用Context.startservice()不會嵌套(即使會有相應的onStart()方法被調用),所以無論同一個服務被啓動了多少次,一旦調用Context.stopService()或者stopSelf(),他都會被停止。補充說明:傳遞給startService()的Intent對象會傳遞給onStart()方法。調用順序爲:onCreate --> onStart(可多次調用) --> onDestroy。 
(2)Context.bindService():Service會經歷onCreate() -> onBind(),onBind將返回給客戶端一個IBind接口實例,IBind允許客戶端回調服務的方法,比如得到Service運行的狀態或其他操作。這個時候把調用者(Context,例如Activity)會和Service綁定在一起,Context退出了,Srevice就會調用onUnbind -> onDestroyed相應退出,所謂綁定在一起就共存亡了 
補充說明:傳遞給bindService()的Intent對象會傳遞給onBind(),傳遞給unbindService()的Intent對象會傳遞給onUnbind()方法 調用順序爲:onCreate --> onBind(只一次,不可多次綁定) --> onUnbind --> onDestory。
(3)注意事項:在Service每一次的開啓關閉過程中,只有onStart可被多次調用(通過多次startService調用),其他onCreate,onBind,onUnbind,onDestory在一個生命週期中只能被調用一次。還有一點,目前我沒有遇到過需要startService和bindService交互使用的情況(我認爲不會有這種需求),所以不必去考慮交互的問題,待遇到時再考慮不遲。
(4)BroadcastReceiver只能通過startService啓動Service ,因爲廣播本身生命週期很短,bind的話沒有意義:Method bindService can not be called from an BroadcastReceiver component. A pattern you can use to communicate from an BroadcastReceiver to a Service is to call startService(Intent) with the arguments containing the command to be sent, with the service calling its stopSelf(int) method when done executing that command. See the API demo App/Service/Service Start Arguments Controller for an illustration of this. It is okay, however, to use this method from an BroadcastReceiver that has been registered with registerReceiver(BroadcastReceiver, IntentFilter), since the lifetime of this BroadcastReceiver is tied to another object (the one that registered it).

 

3. 示例代碼

(1)調用者Activity

Java代碼
  1. public class TServiceHolder extends Activity {   
  2.     private boolean isBound;   
  3.     private TService tService;   
  4.     private int statusCode;   
  5.        
  6.     private ServiceConnection conn = new ServiceConnection() {   
  7.         // Called when a connection to the Service has been established, with the IBinder of the communication channel to the Service.   
  8.         public void onServiceConnected(ComponentName name, IBinder service) {   
  9.              tService = ( (TService.LocalBinder) service ).getService();   
  10.              statusCode = ( (TService.LocalBinder) service ).getStatusCode();   
  11.              Toast.makeText(TServiceHolder.this"Service Connected", Toast.LENGTH_SHORT).show();   
  12.          }   
  13.            
  14.         //無法被觸發,原因未能找到   
  15.         public void onServiceDisconnected(ComponentName name) {   
  16.              tService = null;   
  17.              Toast.makeText(TServiceHolder.this"Service DisConnected", Toast.LENGTH_SHORT).show();   
  18.          }   
  19.      };   
  20.     public void onCreate(Bundle savedInstanceState) {   
  21.         super.onCreate(savedInstanceState);   
  22.          setContentView(R.layout.main);   
  23.          initButtons();   
  24.      }   
  25.        
  26.     private void initButtons() {   
  27.          Button startButton = (Button) findViewById(R.id.startService);   
  28.          Button bindButton = (Button) findViewById(R.id.bindService);   
  29.          Button unbindButton = (Button) findViewById(R.id.unbindService);   
  30.          Button stopButton = (Button) findViewById(R.id.stopService);   
  31.            
  32.          startButton.setOnClickListener(new Button.OnClickListener() {   
  33.             public void onClick(View v) {   
  34.                  Intent i = new Intent(TServiceHolder.this, TService.class);   
  35.                  TServiceHolder.this.startService(i);   
  36.              }   
  37.          });   
  38.          bindButton.setOnClickListener(new Button.OnClickListener() {   
  39.             public void onClick(View v) {   
  40.                  Intent i = new Intent(TServiceHolder.this, TService.class);   
  41.                  TServiceHolder.this.bindService(i, conn, Context.BIND_AUTO_CREATE);   
  42.                  isBound = true;   
  43.              }   
  44.          });   
  45.          unbindButton.setOnClickListener(new Button.OnClickListener() {   
  46.             public void onClick(View v) {   
  47.                 if (isBound) {   
  48.                      TServiceHolder.this.unbindService(conn);   
  49.                      isBound = false;   
  50.                  }   
  51.              }   
  52.          });   
  53.          stopButton.setOnClickListener(new Button.OnClickListener() {   
  54.             public void onClick(View v) {   
  55.                  Intent i = new Intent(TServiceHolder.this, TService.class);   
  56.                  TServiceHolder.this.stopService(i);   
  57.              }   
  58.          });   
  59.      }   
  60.        
  61. }  

(2)Service

Java代碼
  1. public class TService extends android.app.Service {   
  2.     private final String TAG = "Service";   
  3.     private final int NOTIFICATION_ID = 1;   
  4.     private NotificationManager nManager;   
  5.        
  6.     private LocalBinder localBinder = new LocalBinder();   
  7.     private int statusCode;   
  8.        
  9.     public void onCreate() {   
  10.          Log.i(TAG, "Service.onCreate");   
  11.          nManager = (NotificationManager) getSystemService(android.content.Context.NOTIFICATION_SERVICE);   
  12.          showNotification();   
  13.      }   
  14.     private void showNotification() {   
  15.          Notification n = new Notification(R.drawable.face_1, "Service啓動", System.currentTimeMillis());   
  16.          PendingIntent contentIntent = PendingIntent.getActivity(this0new Intent(this, TServiceHolder.class), 0);   
  17.          n.setLatestEventInfo(this"任務標題""任務內容", contentIntent);   
  18.          nManager.notify(NOTIFICATION_ID, n); // 任務欄啓動   
  19.      }   
  20.     public void onStart(Intent intent, int startId) {   
  21.          Log.i(TAG, "Service.onStart");   
  22.      }   
  23.     public IBinder onBind(Intent intent) {   
  24.          Log.i(TAG, "Service.onBind");   
  25.         /*
  26.           * 調用者和Service間是依靠IBinder對象進行通信的,Service的onBind()返回的IBinder對象傳遞給調用者中ServiceConnection對象的onServiceConnected()方法(以參數形式接收);
  27.           * TService的調用者就可以利用這個IBinder獲得TService對象,進而對TService進行操作控制;
  28.           * TService的調用者也可以利用這個IBinder獲得其他信息,比如TService的狀態statusCode。
  29.           */   
  30.         return localBinder;   
  31.      }   
  32.     /*
  33.       * 當應用程序bind一個Service後,該應用程序和Service之間就能進行互相通信,通常,這種通信的完成依靠於我們定義的一些接口,例如下面的LocalBinder。
  34.       */  
  35.     class LocalBinder extends Binder {   
  36.         public TService getService() {   
  37.             return TService.this// Service本身   
  38.          }   
  39.         public int getStatusCode() {   
  40.             return statusCode;   
  41.          }   
  42.      }   
  43.     public void onRebind(Intent i) {   
  44.          Log.i(TAG, "Service.onRebind");   
  45.      }   
  46.     public boolean onUnbind(Intent i) {   
  47.          Log.i(TAG, "Service.onUnbind");   
  48.         return false;   
  49.      }   
  50.     public void onDestroy() {   
  51.          nManager.cancel(NOTIFICATION_ID); // 任務欄關閉   
  52.          Log.i(TAG, "Service.onDestroy");   
  53.      }   
  54. }  

4. 與遠程Service通信(進程間Service通信)

如何兩個進程間的Service需要進行通信,則需要把對象序列化後進行互相發送。
Android提供了一個 AIDL (Android接口定義語言)工具來處理序列化和通信。這種情況下Service需要以aidl文件的方式提供服務接口,AIDL工具將生成一個相應的java接口,並且在生成的服務接口中包含一個功能調用的stub服務樁類。Service的實現類需要去繼承這個 stub服務樁類。Service的onBind方法會返回實現類的對象,之後你就可以使用它了,參見下例:
先創建一個IMyRemoteService.aidl文件,內容如下:

package com.wissen.testApp;

interface IMyRemoteService {
    int getStatusCode();
}

如果你正在使用eclipse的 Android插件,則它會根據這個aidl文件生成一個Java接口類。生成的接口類中會有一個內部類Stub類,你要做的事就是去繼承該Stub類:

package com.wissen.testApp;

class RemoteService implements Service {
    int statusCode;
   
    @Override
    public IBinder onBind(Intent arg0) {
        return myRemoteServiceStub;
    }

    private IMyRemoteService.Stub myRemoteServiceStub = new IMyRemoteService.Stub() {
        public int getStatusCode() throws RemoteException {
            return 0;
        }
    };
   
    …
}

當客戶端應用連接到這個Service時,onServiceConnected方法將被調用,客戶端就可以獲得IBinder對象。參看下面的客戶端onServiceConnected方法:


ServiceConnection conn = new ServiceConnection() {
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        IMyRemoteService myRemoteService = IMyRemoteService.Stub.asInterface(service);
        try {
            statusCode = myRemoteService.getStatusCode();
       } catch(RemoteException e) {
           // handle exception
       }
        Log.i(”INFO”, “Service bound “);
    }
   
    …
};

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章