最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Android 進(jìn)程間通信實現(xiàn)原理分析

 更新時間:2013年06月03日 16:27:00   作者:  
只有你允許客戶端從不同的應(yīng)用程序為了進(jìn)程間的通信而去訪問你的service,以及想在你的service處理多線程,下面為大家詳細(xì)介紹下

Android Service是分為兩種:
  本地服務(wù)(Local Service): 同一個apk內(nèi)被調(diào)用
  遠(yuǎn)程服務(wù)(Remote Service):被另一個apk調(diào)用
遠(yuǎn)程服務(wù)需要借助AIDL來完成。

AIDL 是什么
  AIDL (Android Interface Definition Language) 是一種IDL 語言,用于生成可以在Android設(shè)備上兩個進(jìn)程之間進(jìn)行進(jìn)程間通信(interprocess communication, IPC)的代碼。如果在一個進(jìn)程中(例如Activity)要調(diào)用另一個進(jìn)程中(例如Service)對象的操作,就可以使用AIDL生成可序列化的參數(shù)。
  AIDL IPC機(jī)制是面向接口的,像COM或Corba一樣,但是更加輕量級。它是使用代理類在客戶端和實現(xiàn)端傳遞數(shù)據(jù)。

AIDL 的作用
  由于每個應(yīng)用程序都運(yùn)行在自己的進(jìn)程空間,并且可以從應(yīng)用程序UI運(yùn)行另一個服務(wù)進(jìn)程,而且經(jīng)常會在不同的進(jìn)程間傳遞對象。在Android平臺,一個進(jìn)程通常不能訪問另一個進(jìn)程的內(nèi)存空間,所以要想對話,需要將對象分解成操作系統(tǒng)可以理解的基本單元,并且有序的通過進(jìn)程邊界。
  通過代碼來實現(xiàn)這個數(shù)據(jù)傳輸過程是冗長乏味的,Android提供了AIDL工具來處理這項工作。

選擇AIDL的使用場合
  官方文檔特別提醒我們何時使用AIDL是必要的:只有你允許客戶端從不同的應(yīng)用程序為了進(jìn)程間的通信而去訪問你的service,以及想在你的service處理多線程。
  如果不需要進(jìn)行不同應(yīng)用程序間的并發(fā)通信(IPC),you should create your interface by implementing a Binder;或者你想進(jìn)行IPC,但不需要處理多線程的,則implement your interface using a Messenger。無論如何,在使用AIDL前,必須要理解如何綁定service——bindService。

下面將要講到的這個例子來自:http://www.cnblogs.com/lonkiss/archive/2012/10/23/2735548.html

下面用一個客戶端Activity操作服務(wù)端Service播放音樂的實例演示AIDL的使用。

服務(wù)端代碼結(jié)構(gòu)(左)                                 客戶端代碼結(jié)構(gòu)(右)
被標(biāo)記的就是需要動手的。
服務(wù)端

新建一個android application project,命名為PlayerServer。 在res下的raw文件夾里面放入一個音樂文件,我這里放入的是Delta Goodrem的《Lost Without You》片段。如果不存在raw這個文件夾就自己新建一個,命名為raw。這個文件夾在raw文件夾下,與layout文件夾平級。raw中的文件遵守標(biāo)識符的命名規(guī)則,不要出現(xiàn)中文和空格,多個單詞可以用下劃線連接。
  
新建一個IRemoteServiice.aidl 文件,加入如下代碼

復(fù)制代碼 代碼如下:

package pandafang.demo.playerserver;
interface IRemoteService {
 void play();
 void stop();
}

可見aidl文件的代碼跟java的interface一樣,但是aidl中不能加public等修飾符。Ctrl + S 保存后 ADT 會根據(jù)這個IRemoteService.aidl文件自動生成IRemoteService.java文件。如同R.java文件一樣在“gen/包名”下,代碼是自動生成的,不要手動修改。
  
接下來就是bound service的知識了。IRemoteService.java 中有一個Stub靜態(tài)抽象類extends Binder implements IRemoteService。自己動手寫一個PlayerService 用來播放音樂,播放音樂需要使用

android.media.MediaPlayer類。代碼如下

復(fù)制代碼 代碼如下:

/**
 * 播放音樂的服務(wù)
 */
public class PlayerService extends Service {

 public static final String TAG = "PlayerService";

 private MediaPlayer mplayer;

 @Override
 public IBinder onBind(Intent intent) {
  Log.i(TAG,"service onbind");
  if(mplayer==null){
   // 方法一說明
   // 此方法實例化播放器的同時指定音樂數(shù)據(jù)源 ,若用此方法在,mplayer.start() 之前不需再調(diào)用mplayer.prepare()
   // 官方文檔有說明 :On success, prepare() will already have been called and must not be called again.
   // 譯文:一旦create成功,prepare已被調(diào)用,勿再調(diào)用 。查看源代碼可知create方法內(nèi)部已經(jīng)調(diào)用prepare方法。
   // 方法一開始
   // mplayer = MediaPlayer.create(this, R.raw.lost);
   // 方法一結(jié)束

   // 方法二說明
   // 若用此方法,在mplayer.start() 之前需要調(diào)用mplayer.prepare()
   // 方法二開始
   mplayer = new MediaPlayer();
   try {
    FileDescriptor fd = getResources().openRawResourceFd(R.raw.lost).getFileDescriptor(); // 獲取音樂數(shù)據(jù)源
    mplayer.setDataSource(fd); // 設(shè)置數(shù)據(jù)源
    mplayer.setLooping(true); // 設(shè)為循環(huán)播放
   } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
   // 方法二結(jié)束
   Log.i(TAG,"player created");
  }
  return mBinder;
 }

 // 實現(xiàn)aidl文件中定義的接口
 private IBinder mBinder = new IRemoteService.Stub() {

  @Override
  public void stop() throws RemoteException {
   try {
    if (mplayer.isPlaying()) {
     mplayer.stop();
    }
   } catch (Exception e) {
    // TODO: handle exception
    e.printStackTrace();
   }
  }

  @Override
  public void play() throws RemoteException {
   try {
    if (mplayer.isPlaying()) {
     return;
    }
    // start之前需要prepare。
    // 如果前面實例化mplayer時使用方法一,則第一次play的時候直接start,不用prepare。
    // 但是stop一次之后,再次play就需要在start之前prepare了。
    // 前面使用方法二 這里就簡便了, 不用判斷各種狀況
    mplayer.prepare();
    mplayer.start();
   } catch (Exception e) {
    // TODO: handle exception
    e.printStackTrace();
   }
  }
 };
 @Override
 public boolean onUnbind(Intent intent) {
  if (mplayer != null) {
   mplayer.release();
  }
  Log.i(TAG,"service onUnbind");
  return super.onUnbind(intent);
 }
}

服務(wù)編寫好以后,按照慣例在AndroidManifest.xml中加入聲明,代碼如下
復(fù)制代碼 代碼如下:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="pandafang.demo.playerserver"
    android:versionCode="1"
    android:versionName="1.0" >
    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="15" />
    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <service android:name=".PlayerService" android:process=":remote">
            <intent-filter >
                <action android:name="com.example.playerserver.PlayerService"/>
            </intent-filter>
         </service>
    </application>
</manifest>

需要加入的只是<service>...</service>那段,要注意的是 android:process=":remote" 和 intent-filter 。
  運(yùn)行服務(wù)端到設(shè)備上,準(zhǔn)備給客戶端調(diào)用
客戶端
  新建一個android application project,命名為PlayerClient。將服務(wù)端放有aidl文件的包直接copy到客戶
端src目錄下,保留包中的aidl文件,其他刪除。
 編寫MainActivity.java 代碼如下
復(fù)制代碼 代碼如下:

/**
 * 客戶端控制界面
 */
public class MainActivity extends Activity {

 public static final String TAG = "MainActivity";

 // 服務(wù)端 AndroidManifest.xml中的intent-filter action聲明的字符串
 public static final String ACTION = "com.example.playerserver.PlayerService";

 private Button playbtn, stopbtn;

 private IRemoteService mService;

 private boolean isBinded = false;

 private ServiceConnection conn = new ServiceConnection() {

  @Override
  public void onServiceDisconnected(ComponentName name) {
   isBinded = false;
   mService = null;
  }

  @Override
  public void onServiceConnected(ComponentName name, IBinder service) {
   mService = IRemoteService.Stub.asInterface(service);
   isBinded = true;
  }
 };
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        doBind();
        initViews();
    }
    private void initViews() {
     playbtn = (Button) findViewById(R.id.button1);
        stopbtn = (Button) findViewById(R.id.button2);
        playbtn.setOnClickListener(clickListener);
        stopbtn.setOnClickListener(clickListener);
    }
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }
    @Override
    protected void onDestroy() {
  doUnbind();
     super.onDestroy();
    }
    public void doBind() {
     Intent intent = new Intent(ACTION);
     bindService(intent, conn, Context.BIND_AUTO_CREATE);
    }
    public void doUnbind() {
     if (isBinded) {
      unbindService(conn);
         mService = null;
         isBinded = false;
     }

    }
    private OnClickListener clickListener = new OnClickListener() {

  @Override
  public void onClick(View v) {
   if (v.getId() == playbtn.getId()) {
    // play
    Log.i(TAG,"play button clicked");
    try {
     mService.play();
    } catch (RemoteException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
    }
   } else {
    // stop
    Log.i(TAG,"stop button clicked");
    try {
     mService.stop();
    } catch (RemoteException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
    }
   }
  }
 };
}

MainActivity是根據(jù)向?qū)ё詣由傻模恍枰贏ndroidManifest.xml中注冊聲明了
運(yùn)行客戶端到設(shè)備,按下按鈕可以播放/停止 效果如圖

如果想對更加詳細(xì)的實現(xiàn)原理進(jìn)行研究,可以參見這篇文章:
http://www.cnblogs.com/over140/archive/2011/03/08/1976890.html

相關(guān)文章

  • Android開發(fā)之Android.mk模板的實例詳解

    Android開發(fā)之Android.mk模板的實例詳解

    這篇文章主要介紹了Android開發(fā)之Android.mk模板的實例詳解的相關(guān)資料,希望通過本文能幫助到大家,讓大家理解掌握這部分內(nèi)容,需要的朋友可以參考下
    2017-10-10
  • Android使用音頻信息繪制動態(tài)波紋

    Android使用音頻信息繪制動態(tài)波紋

    這篇文章主要介紹了Android使用音頻信息繪制動態(tài)波紋 的相關(guān)資料,需要的朋友可以參考下
    2016-02-02
  • iOS UIButton 點擊無響應(yīng)的解決辦法

    iOS UIButton 點擊無響應(yīng)的解決辦法

    在開發(fā)中按鈕我們經(jīng)常會遇到,但是有時候會碰到一些難以處理的問題,就是按鈕點擊無響應(yīng),其實解決方法也不難。下面小編之家小編抽空給大家介紹iOS UIButton 點擊無響應(yīng)的解決辦法,需要的朋友參考下吧
    2017-12-12
  • Android APP與媒體存儲服務(wù)的交互

    Android APP與媒體存儲服務(wù)的交互

    本文介紹如何在 Android 中,開發(fā)者的 APP 如何使用媒體存儲服務(wù)(包含MediaScanner、MediaProvider以及媒體信息解析等部分),包括如何把 APP 新增或修改的文件更新到媒體數(shù)據(jù)庫、如何在多媒體應(yīng)用中隱藏 APP 產(chǎn)生的文件、如何監(jiān)聽媒體數(shù)據(jù)庫的變化等等。
    2013-10-10
  • Android上實現(xiàn)RTSP服務(wù)器的方法

    Android上實現(xiàn)RTSP服務(wù)器的方法

    在Android平臺實現(xiàn)RTSP服務(wù)器是一項挑戰(zhàn)性任務(wù),旨在無需部署獨立的RTSP/RTMP服務(wù),通過內(nèi)置輕量級RTSP服務(wù),實現(xiàn)本地音視頻數(shù)據(jù)的對外共享,本文介紹Android上實現(xiàn)RTSP服務(wù)器的方法,感興趣的朋友一起看看吧
    2024-11-11
  • android 6.0 寫入SD卡的權(quán)限申請實例講解

    android 6.0 寫入SD卡的權(quán)限申請實例講解

    今天小編就為大家分享一篇android 6.0 寫入SD卡的權(quán)限申請實例講解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-08-08
  • Android Handler源碼深入探究

    Android Handler源碼深入探究

    handler其實就是主線程在起了一個子線程,子線程運(yùn)行并生成Message,Looper獲取message并傳遞給Handler,Handler逐個獲取子線程中的Message
    2022-08-08
  • 淺談Android invalidate 分析

    淺談Android invalidate 分析

    本篇文章主要介紹了淺談Android invalidate 分析,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-04-04
  • Android自定義照相機(jī)詳解

    Android自定義照相機(jī)詳解

    幾乎每個APP都會用的相機(jī)功能,下面小編把內(nèi)容整理分享到腳本之家平臺,供大家參考
    2016-04-04
  • Android自定義View實現(xiàn)掃描效果

    Android自定義View實現(xiàn)掃描效果

    這篇文章主要為大家詳細(xì)介紹了Android自定義View實現(xiàn)掃描效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-04-04

最新評論

巴南区| 德江县| 大城县| 渝中区| 新建县| 荣成市| 秦皇岛市| 会东县| 闽清县| 双江| 抚顺市| 普陀区| 五河县| 台湾省| 辽阳县| 维西| 东源县| 和林格尔县| 红桥区| 柏乡县| 咸丰县| 赤水市| 新兴县| 额尔古纳市| 清丰县| 高密市| 武夷山市| 郴州市| 柘荣县| 望奎县| 台南县| 乐业县| 蒙城县| 抚松县| 南澳县| 新蔡县| 黄龙县| 孝义市| 清丰县| 潼关县| 临猗县|