• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            life02

              C++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
              197 隨筆 :: 3 文章 :: 37 評論 :: 0 Trackbacks
            http://blog.csdn.net/sunboy_2050/article/details/7366396

            一、bindService簡介

            bindService是綁定Service服務,執行service服務中的邏輯流程。

            service 通過Context.startService()方法開始,通過Context.stopService()方法停止;也可以通過 Service.stopSelf()方法或者Service.stopSelfResult()方法來停止自己。只要調用一次 stopService()方法便可以停止服務,無論之前它被調用了多少次的啟動服務方法。

             

            客戶端建立一個與 Service的鏈接,并使用此鏈接與Service進行通話,通過Context.bindService()方法來綁定服 務,Context.unbindService()方法來關閉服務。多個客戶端可以綁定同一個服務,如果Service還未被啟 動,bindService()方法可以啟動服務。

             

            上面startService()和bindService()兩種模 式是完全獨立的。你可以綁定一個已經通過startService()方法啟動的服務。例如:一個后臺播放音樂服務可以通過 startService(intend)對象來播放音樂。可能用戶在播放過程中要執行一些操作比如獲取歌曲的一些信息,此時activity可以通過調 用bindServices()方法與Service建立連接。這種情況下,stopServices()方法實際上不會停止服務,直到最后一次綁定關 閉。


            二、bindService啟動流程

            context.bindService()  -> onCreate()  -> onBind()  -> Service running  -> onUnbind()  -> onDestroy()  -> Service stop
             

            onBind() 將返回給客戶端一個IBind接口實例,IBind允許客戶端回調服務的方法,比如得到Service的實例、運行狀態或其他操作。這個時候把調用者 (Context,例如Activity)會和Service綁定在一起,Context退出了,Srevice就會調用 onUnbind->onDestroy相應退出。 

            所以調用bindService的生命周期為:onCreate --> onBind(只一次,不可多次綁定) --> onUnbind --> onDestory。

            在Service每一次的開啟關閉過程中,只有onStart可被多次調用(通過多次startService調用),其他onCreate,onBind,onUnbind,onDestory在一個生命周期中只能被調用一次。詳見:Android Service 服務(一)—— Service


            三、bindService生命周期

            像一個activity那樣,一個service有些可以用來改變狀態的生命周期方法,但是比activity的方法少,service生命周期方法只有三個public

               void onCreate()

               void onStart(Intent intent)

               void onDestroy()

            通過實現這三個生命周期方法,你可以監聽service的兩個嵌套循環的生命周期:

            1、整個生命周期

             service 的整個生命周期是在onCreate()和onDestroy()方法之間。和activity一樣,在onCreate()方法里初始化,在 onDestroy()方法里釋放資源。例如,一個背景音樂播放服務可以在onCreate()方法里播放,在onDestroy()方法里停止。

             

            2、活動的生命周期

             service 的活動生命周期是在onStart()之后,這個發法會處理通過startServices()方法傳遞來的Intent對象。音樂service可以通 過開打intent對象來找到要播放的音樂,然后開始后臺播放。注: service停止時沒有相應的回調方法,即沒有onStop()方法。

             

            onCreate()方法和onDestroy()方法是針對所有的services,無論它們是否啟動,通過Context.startService()和Context.bindService()方法都可以訪問執行。然而,只有通過startService()方法啟動service服務時才會調用onStart()方法

             

            如果一個service允許別人綁定,那么需要實現以下額外的方法:

                   IBinder onBind(Intent intent)

                   boolean onUnbind(Intent intent)

                   void onRebind(Intent intent)

            onBind()回調方法會繼續傳遞通過bindService()傳遞來的intent對像

            onUnbind()會處理傳遞給unbindService()的intent對象。如果service允許綁定,onBind()會返回客戶端與服務互相聯系的通信句柄(實例)。

            如果建立了一個新的客戶端與服務的鏈接,onUnbind()方法可以請求調用onRebind()方法。


            記住任何服務,無論它怎樣建立,都默認客戶端可以鏈接,所以任何的service能夠接收onBind()和onUnbind()方法


            四、bindService示例

            Activity

            1. public class PlayBindMusic extends Activity implements OnClickListener {  
            2.   
            3.     private Button playBtn;  
            4.     private Button stopBtn;  
            5.     private Button pauseBtn;  
            6.     private Button exitBtn;  
            7.   
            8.     private BindMusicService musicService;  
            9.   
            10.     @Override  
            11.     public void onCreate(Bundle savedInstanceState) {  
            12.         super.onCreate(savedInstanceState);  
            13.   
            14.         setContentView(R.layout.bind_music_service);  
            15.   
            16.         playBtn = (Button) findViewById(R.id.play);  
            17.         stopBtn = (Button) findViewById(R.id.stop);  
            18.         pauseBtn = (Button) findViewById(R.id.pause);  
            19.         exitBtn = (Button) findViewById(R.id.exit);  
            20.   
            21.         playBtn.setOnClickListener(this);  
            22.         stopBtn.setOnClickListener(this);  
            23.         pauseBtn.setOnClickListener(this);  
            24.         exitBtn.setOnClickListener(this);  
            25.   
            26.         connection();  
            27.     }  
            28.   
            29.     private void connection() {  
            30.         Intent intent = new Intent("com.homer.bind.bindService");  
            31.         bindService(intent, sc, Context.BIND_AUTO_CREATE);          // bindService  
            32.     }  
            33.   
            34.     @Override  
            35.     public void onClick(View v) {  
            36.         switch (v.getId()) {  
            37.         case R.id.play:  
            38.             musicService.play();  
            39.             break;  
            40.         case R.id.stop:  
            41.             if (musicService != null) {  
            42.                 musicService.stop();  
            43.             }  
            44.             break;  
            45.         case R.id.pause:  
            46.             if (musicService != null) {  
            47.                 musicService.pause();  
            48.             }  
            49.             break;  
            50.         case R.id.exit:  
            51.             this.finish();  
            52.             break;  
            53.         }  
            54.     }  
            55.   
            56.     private ServiceConnection sc = new ServiceConnection() {  
            57.   
            58.         @Override  
            59.         public void onServiceConnected(ComponentName name, IBinder service) {       //connect Service  
            60.             musicService = ((BindMusicService.MyBinder) (service)).getService();  
            61.             if (musicService != null) {  
            62.                 musicService.play();        // play music  
            63.             }  
            64.         }  
            65.           
            66.         @Override  
            67.         public void onServiceDisconnected(ComponentName name) {                 //disconnect Service  
            68.             musicService = null;  
            69.         }  
            70.     };  
            71.       
            72.     @Override  
            73.     public void onDestroy(){  
            74.         super.onDestroy();  
            75.           
            76.         if(sc != null){  
            77.             unbindService(sc);  
            78.         }  
            79.     }  
            80. }  

            Service
            1. public class BindMusicService extends Service {  
            2.   
            3.     private MediaPlayer mediaPlayer;  
            4.   
            5.     private final IBinder binder = new MyBinder();  
            6.   
            7.     public class MyBinder extends Binder {  
            8.         BindMusicService getService() {  
            9.             return BindMusicService.this;  
            10.         }  
            11.     }  
            12.   
            13.     @Override  
            14.     public IBinder onBind(Intent intent) {  
            15.         return binder;  
            16.     }  
            17.   
            18.     @Override  
            19.     public void onCreate() {  
            20.         super.onCreate();  
            21.           
            22.         Toast.makeText(this, "show media player", Toast.LENGTH_SHORT).show();  
            23.     }  
            24.   
            25.     @Override  
            26.     public void onDestroy() {  
            27.         super.onDestroy();  
            28.           
            29.         Toast.makeText(this, "stop media player", Toast.LENGTH_SHORT);  
            30.         if(mediaPlayer != null){  
            31.             mediaPlayer.stop();  
            32.             mediaPlayer.release();  
            33.         }  
            34.     }  
            35.   
            36.       
            37.     public void play() {  
            38.         if (mediaPlayer == null) {  
            39.             mediaPlayer = MediaPlayer.create(this, R.raw.tmp);  
            40.             mediaPlayer.setLooping(false);  
            41.         }  
            42.         if (!mediaPlayer.isPlaying()) {  
            43.             mediaPlayer.start();  
            44.         }  
            45.     }  
            46.   
            47.     public void pause() {  
            48.         if (mediaPlayer != null && mediaPlayer.isPlaying()) {  
            49.             mediaPlayer.pause();  
            50.         }  
            51.     }  
            52.   
            53.     public void stop() {  
            54.         if (mediaPlayer != null) {  
            55.             mediaPlayer.stop();  
            56.             try {  
            57.                 mediaPlayer.prepare();      // 在調用stop后如果需要再次通過start進行播放,需要之前調用prepare函數  
            58.             } catch (IOException ex) {  
            59.                 ex.printStackTrace();  
            60.             }  
            61.         }  
            62.     }  
            63. }  

            AndroidManifest.xml
            1. <service  
            2.     android:name=".bind.BindMusicService"  
            3.     android:enabled="true" >  
            4.     <intent-filter>  
            5.         <action android:name="com.homer.bind.bindService" />  
            6.     </intent-filter>  
            7. </service>  


            五、代碼解析

            1、 Activity中,Intent intent = new Intent("com.homer.bind.bindService"); 構建一個service的action,然后bindService(intent, sc, Context.BIND_AUTO_CREATE); 綁定服務

            2、 Activity中,通過private ServiceConnection sc = new ServiceConnection() 建立一個Service連接,onServiceConnected()獲取Service實例,onServiceDisconnected()釋放連 接

            3、 Service中,重載onBind(Intent intent)方法,返回Service實例(即BindMusicService)給Activity,然后執行onCreate()函數(注:bindService不執行onStart()函數)

            4、 Activity中,通過返回的Service實例musicService,執行音樂播放的操作(play、pause、stop等)


            六、Remote Service拓展

            通 常每個應用程序都在它自己的進程內運行,但有時需要在進程之間傳遞對象(IPC通信),你可以通過應用程序UI的方式寫個運行在一個不同的進程中的 service。在android平臺中,一個進程通常不能訪問其它進程中的內存區域。所以,他們需要把對象拆分成操作系統能理解的簡單形式,以便偽裝成 對象跨越邊界訪問。編寫這種偽裝代碼相當的枯燥乏味,好在android為我們提供了AIDL工具可以來做這件事。
             
            AIDL(android 接口描述語言)是一個IDL語言,它可以生成一段代碼,可以使在一個android設備上運行的兩個進程使用內部通信進程進行交互。如果你需要在一個進程 中(例如在一個Activity中)訪問另一個進程中(例如一個Service)某個對象的方法,你就可以使用AIDL來生成這樣的代碼來偽裝傳遞各種參數
             
            要 使用AIDL,Service需要以aidl文件的方式提供服務接口,AIDL工具將生成一個相應的java接口,并且在生成的服務接口中包含一個功能調 用的stub服務樁類。Service的實現類需要去繼承這個stub服務樁類。Service的onBind方法會返回實現類的對象,之后你就可以使用 它了,參見下例:

            IMusicControlService.aidl

            1. package com.homer.remote;  
            2.   
            3. interface IMusicControlService{  
            4.         void play();   
            5.         void stop();   
            6.         void pause();  
            7. }  
            使用eclipse的Android插件,會根據這個aidl文件生成一個Java接口類,生成的接口類中會有一個內部類Stub類,Service來繼承該Stub類:
            Service
            1. public class RemoteMusicService extends Service {  
            2.   
            3.     private MediaPlayer mediaPlayer;  
            4.   
            5.     @Override  
            6.     public IBinder onBind(Intent intent) {  
            7.         return binder;  
            8.     }  
            9.   
            10.     private final IMusicControlService.Stub binder = new IMusicControlService.Stub() {  
            11.   
            12.         @Override  
            13.         public void play() throws RemoteException {  
            14.             if (mediaPlayer == null) {  
            15.                 mediaPlayer = MediaPlayer.create(RemoteMusicService.this, R.raw.tmp);  
            16.                 mediaPlayer.setLooping(false);  
            17.             }  
            18.             if (!mediaPlayer.isPlaying()) {  
            19.                 mediaPlayer.start();  
            20.             }  
            21.         }  
            22.   
            23.         @Override  
            24.         public void pause() throws RemoteException {  
            25.             if (mediaPlayer != null && mediaPlayer.isPlaying()) {  
            26.                 mediaPlayer.pause();  
            27.             }             
            28.         }  
            29.   
            30.         @Override  
            31.         public void stop() throws RemoteException {  
            32.             if (mediaPlayer != null) {  
            33.                 mediaPlayer.stop();  
            34.                 try {  
            35.                     mediaPlayer.prepare();      // 在調用stop后如果需要再次通過start進行播放,需要之前調用prepare函數  
            36.                 } catch (IOException ex) {  
            37.                     ex.printStackTrace();  
            38.                 }  
            39.             }  
            40.         }  
            41.     };  
            42.       
            43.     @Override  
            44.     public void onDestroy() {  
            45.         super.onDestroy();  
            46.           
            47.         if(mediaPlayer != null){  
            48.             mediaPlayer.stop();  
            49.             mediaPlayer.release();  
            50.         }  
            51.     }  
            52. }  

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

            Activity

            1. public class PlayRemoteMusic extends Activity implements OnClickListener {  
            2.   
            3.     private Button playBtn;  
            4.     private Button stopBtn;  
            5.     private Button pauseBtn;  
            6.     private Button exitBtn;  
            7.   
            8.     private IMusicControlService musicService;  
            9.   
            10.     @Override  
            11.     public void onCreate(Bundle savedInstanceState) {  
            12.         super.onCreate(savedInstanceState);  
            13.         setContentView(R.layout.remote_music_service);  
            14.   
            15.         playBtn = (Button) findViewById(R.id.play);  
            16.         stopBtn = (Button) findViewById(R.id.stop);  
            17.         pauseBtn = (Button) findViewById(R.id.pause);  
            18.         exitBtn = (Button) findViewById(R.id.exit);  
            19.   
            20.         playBtn.setOnClickListener(this);  
            21.         stopBtn.setOnClickListener(this);  
            22.         pauseBtn.setOnClickListener(this);  
            23.         exitBtn.setOnClickListener(this);  
            24.   
            25.         connection();  
            26.     }  
            27.   
            28.     private void connection() {  
            29.         Intent intent = new Intent("com.homer.remote.remoteMusicReceiver");  
            30.         bindService(intent, sc, Context.BIND_AUTO_CREATE);              // bindService  
            31.     }  
            32.   
            33.     @Override  
            34.     public void onClick(View v) {  
            35.   
            36.         try {  
            37.             switch (v.getId()) {  
            38.             case R.id.play:  
            39.                 musicService.play();  
            40.                 break;  
            41.             case R.id.stop:  
            42.                 if (musicService != null) {  
            43.                     musicService.stop();  
            44.                 }  
            45.                 break;  
            46.             case R.id.pause:  
            47.                 if (musicService != null) {  
            48.                     musicService.pause();  
            49.                 }  
            50.                 break;  
            51.             case R.id.exit:  
            52.                 this.finish();  
            53.                 break;  
            54.             }  
            55.         } catch (RemoteException e) {  
            56.             e.printStackTrace();  
            57.         }  
            58.     }  
            59.   
            60.     private ServiceConnection sc = new ServiceConnection() {  
            61.         @Override  
            62.         public void onServiceConnected(ComponentName name, IBinder service) {       //connect Service  
            63.             musicService = IMusicControlService.Stub.asInterface(service);  
            64.         }  
            65.   
            66.         @Override  
            67.         public void onServiceDisconnected(ComponentName name) {                 //disconnect Service  
            68.             musicService = null;  
            69.         }  
            70.   
            71.     };  
            72.       
            73.     @Override  
            74.     public void onDestroy(){  
            75.         super.onDestroy();  
            76.           
            77.         if(sc != null){  
            78.             unbindService(sc);              // unBindService  
            79.         }  
            80.     }  
            81. }  

            Remote Service流程總結:

            1、 Activity(客戶端)中,Intent intent = new Intent("com.homer.remote.remoteMusicReceiver");構建intent,然后 bindService(intent, sc, Context.BIND_AUTO_CREATE);綁定服務

            2、 Activity(客戶端)中,通過ServiceConnection()重載onServiceConnected()建立連接,獲取Service.Stub實例;onServiceDisconnected()釋放連接(與bindService類似)

            3、 Service中,通過重載onBind(Intent intent) 返回Service.Stub實例,但Service.Stub類是由aidl文件生成的接口類中的一個內部類Stub類,Service來繼承該Stub類

            4、 Activity中,通過操作Service實例(musicService),執行音樂播放操作(play、pause、stop等)


            posted on 2012-03-20 14:02 life02 閱讀(1560) 評論(0)  編輯 收藏 引用 所屬分類: android組件學習
            91精品国产乱码久久久久久| 天天做夜夜做久久做狠狠| 久久综合狠狠综合久久综合88| 欧美日韩精品久久久免费观看| 色婷婷综合久久久久中文 | 69久久精品无码一区二区| 国产精品久久精品| 少妇被又大又粗又爽毛片久久黑人| 久久九九兔免费精品6| 一本一道久久精品综合| 久久久久久伊人高潮影院| 欧美激情精品久久久久| 少妇久久久久久被弄高潮| 99久久综合国产精品二区| 欧美丰满熟妇BBB久久久| AA级片免费看视频久久| 久久天天躁狠狠躁夜夜网站| 久久久久人妻一区精品| 久久99久久99精品免视看动漫| 人妻丰满?V无码久久不卡| 久久国产精品国产自线拍免费| 色偷偷久久一区二区三区| 日本WV一本一道久久香蕉| 伊人久久大香线蕉影院95| 乱亲女H秽乱长久久久| 大香伊人久久精品一区二区| 国产精品VIDEOSSEX久久发布| 精品国产VA久久久久久久冰| 亚洲欧美日韩久久精品第一区| 香蕉久久永久视频| 欧美午夜A∨大片久久| 久久久精品人妻无码专区不卡 | 亚洲精品无码专区久久久| 日本精品久久久久影院日本| 久久久99精品成人片中文字幕| 国产99久久久久久免费看| 91精品国产高清久久久久久国产嫩草 | 久久久久无码专区亚洲av| 国内精品久久久久| 久久国产乱子伦精品免费强| 亚洲综合婷婷久久|