日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android Service 之 AIDL

發布時間:2025/3/19 Android 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android Service 之 AIDL 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

  • Create .aidl文件
    定義Service接口
  • Caution: AIDL 做的任何改變,都必須保持后向兼容
    方法支持參數和返回值,參數和返回值可以是任意類型。
    1. 所有Java原型都支持(int, long, float, char ,boolean等)
    2. String
    3. Charsequence
    4. List,元素必須是支持的數據類型,也可是其他AIDL所申明的,或者是parcelables。同時也可使用泛型申明。實際使用ArrayList來存儲元素。
    5. Map,也list要求相同。但不可使用泛型,實際使用HashMap來存儲。

    如果要使用除以上數據的類型其他類型數據,則必須使用import進行申明。

    此外,在定義接口時,還需注意的有:
    1. 方法可為0個或多個參數,可返回值或者void
    2. 所有非原型參數,需要方向標簽,in,out,inout。
    3. 所有代碼注釋都會被生成到java接口中,除了import和package申明之前的。
    4. 只支持方法,不支持靜態成員變量的申明。

    案例

    // IRemoteService.aidl package com.example.android;// Declare any non-default types here with import statements/** Example service interface */ interface IRemoteService {/** Request the process ID of this service, to do evil things with it. */int getPid();/** Demonstrates some basic types that you can use as parameters* and return values in AIDL.*/void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,double aDouble, String aString); }
  • 實現一個接口
    Android SDK tools會根據aidl文件自動生成一個java語言的編程接口,這個接口包含一個繼承于Binder的抽象類和aidl中的接口方法實現。必須繼承Stub然后實現方法。
  • 保存到/src目錄下,ADT tool 會在/gen目錄下生成IBinder接口文件。注意包名。
    生成的接口包含一個子類Stub, 是對接口的抽象實現。因此,需要繼承該Stub,然后實現抽象方法。
    其中Stub還有一個助手方法asInterface(),傳遞IBinder并返回stub接口實例。
    實例代碼如下:

    private final IRemoteService.Stub mBinder = new IRemoteService.Stub() {public int getPid(){return Process.myPid();}public void basicTypes(int anInt, long aLong, boolean aBoolean,float aFloat, double aDouble, String aString) {// Does nothing} };

    Caution: 注意多線程,要確保方法是線程安全的。RPC calls 通常是同步的,所以在client調用時,請使用子線程避免hand up the main thread and encounter ANR.此外,Server端不會返回Exception。

  • Expose the interface to the clients
    繼承Service,重寫onBind(),然后返回Stub 類的實現,即mBinder。
  • public class RemoteService extends Service {@Overridepublic void onCreate() {super.onCreate();}@Overridepublic IBinder onBind(Intent intent) {// Return the interfacereturn mBinder;} }

    Client調用,如果與Server不再同一個Application下,那么需要將aidl文件拷貝到Client,并且保持包名的一致。

    Passing Objects over IPC

    支持Parcelable,將允許Android系統decompose objects into primitives that can be marshalled over processes, 意思就是允許Android系統將objects 解耦成primitives,而這些primitives可在進程間傳遞。
    Step:
    1. 讓需要傳遞的類實現Parcelable接口,
    2. 實現writeToParcel()方法,它將把對象的當前狀態寫到一個Parcel
    3. 添加靜態字段CREATOR,它時實現Parcelable.Creator接口。
    4. create a aidl, 然后申明這個Parcelable 類。

    aidl 申明Rect類代碼如下:

    package android.graphics;// Declare Rect so AIDL can find it and knows that it implements // the parcelable protocol. parcelable Rect;

    接下來是Rect類實現Parcelable接口代碼:

    import android.os.Parcel; import android.os.Parcelable;public final class Rect implements Parcelable {public int left;public int top;public int right;public int bottom;public static final Parcelable.Creator<Rect> CREATOR = new Parcelable.Creator<Rect>() {public Rect createFromParcel(Parcel in) {return new Rect(in);}public Rect[] newArray(int size) {return new Rect[size];}};public Rect() {}private Rect(Parcel in) {readFromParcel(in);}public void writeToParcel(Parcel out) {out.writeInt(left);out.writeInt(top);out.writeInt(right);out.writeInt(bottom);}public void readFromParcel(Parcel in) {left = in.readInt();top = in.readInt();right = in.readInt();bottom = in.readInt();} }

    Calling an IPC Method

    調用遠程服務的實例,在之前的Service節中已經出現過了。這里不妨再贅上,有效長,:)

    public static class Binding extends Activity {/** The primary interface we will be calling on the service. */IRemoteService mService = null;/** Another interface we use on the service. */ISecondary mSecondaryService = null;Button mKillButton;TextView mCallbackText;private boolean mIsBound;/*** Standard initialization of this activity. Set up the UI, then wait* for the user to poke it before doing anything.*/@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.remote_service_binding);// Watch for button clicks.Button button = (Button)findViewById(R.id.bind);button.setOnClickListener(mBindListener);button = (Button)findViewById(R.id.unbind);button.setOnClickListener(mUnbindListener);mKillButton = (Button)findViewById(R.id.kill);mKillButton.setOnClickListener(mKillListener);mKillButton.setEnabled(false);mCallbackText = (TextView)findViewById(R.id.callback);mCallbackText.setText("Not attached.");}/*** Class for interacting with the main interface of the service.*/private ServiceConnection mConnection = new ServiceConnection() {public void onServiceConnected(ComponentName className,IBinder service) {// This is called when the connection with the service has been// established, giving us the service object we can use to// interact with the service. We are communicating with our// service through an IDL interface, so get a client-side// representation of that from the raw service object.mService = IRemoteService.Stub.asInterface(service);mKillButton.setEnabled(true);mCallbackText.setText("Attached.");// We want to monitor the service for as long as we are// connected to it.try {mService.registerCallback(mCallback);} catch (RemoteException e) {// In this case the service has crashed before we could even// do anything with it; we can count on soon being// disconnected (and then reconnected if it can be restarted)// so there is no need to do anything here.}// As part of the sample, tell the user what happened.Toast.makeText(Binding.this, R.string.remote_service_connected,Toast.LENGTH_SHORT).show();}public void onServiceDisconnected(ComponentName className) {// This is called when the connection with the service has been// unexpectedly disconnected -- that is, its process crashed.mService = null;mKillButton.setEnabled(false);mCallbackText.setText("Disconnected.");// As part of the sample, tell the user what happened.Toast.makeText(Binding.this, R.string.remote_service_disconnected,Toast.LENGTH_SHORT).show();}};/*** Class for interacting with the secondary interface of the service.*/private ServiceConnection mSecondaryConnection = new ServiceConnection() {public void onServiceConnected(ComponentName className,IBinder service) {// Connecting to a secondary interface is the same as any// other interface.mSecondaryService = ISecondary.Stub.asInterface(service);mKillButton.setEnabled(true);}public void onServiceDisconnected(ComponentName className) {mSecondaryService = null;mKillButton.setEnabled(false);}};private OnClickListener mBindListener = new OnClickListener() {public void onClick(View v) {// Establish a couple connections with the service, binding// by interface names. This allows other applications to be// installed that replace the remote service by implementing// the same interface.bindService(new Intent(IRemoteService.class.getName()),mConnection, Context.BIND_AUTO_CREATE);bindService(new Intent(ISecondary.class.getName()),mSecondaryConnection, Context.BIND_AUTO_CREATE);mIsBound = true;mCallbackText.setText("Binding.");}};private OnClickListener mUnbindListener = new OnClickListener() {public void onClick(View v) {if (mIsBound) {// If we have received the service, and hence registered with// it, then now is the time to unregister.if (mService != null) {try {mService.unregisterCallback(mCallback);} catch (RemoteException e) {// There is nothing special we need to do if the service// has crashed.}}// Detach our existing connection.unbindService(mConnection);unbindService(mSecondaryConnection);mKillButton.setEnabled(false);mIsBound = false;mCallbackText.setText("Unbinding.");}}};private OnClickListener mKillListener = new OnClickListener() {public void onClick(View v) {// To kill the process hosting our service, we need to know its// PID. Conveniently our service has a call that will return// to us that information.if (mSecondaryService != null) {try {int pid = mSecondaryService.getPid();// Note that, though this API allows us to request to// kill any process based on its PID, the kernel will// still impose standard restrictions on which PIDs you// are actually able to kill. Typically this means only// the process running your application and any additional// processes created by that app as shown here; packages// sharing a common UID will also be able to kill each// other's processes.Process.killProcess(pid);mCallbackText.setText("Killed service process.");} catch (RemoteException ex) {// Recover gracefully from the process hosting the// server dying.// Just for purposes of the sample, put up a notification.Toast.makeText(Binding.this,R.string.remote_call_failed,Toast.LENGTH_SHORT).show();}}}};// ----------------------------------------------------------------------// Code showing how to deal with callbacks.// ----------------------------------------------------------------------/*** This implementation is used to receive callbacks from the remote* service.*/private IRemoteServiceCallback mCallback = new IRemoteServiceCallback.Stub() {/*** This is called by the remote service regularly to tell us about* new values. Note that IPC calls are dispatched through a thread* pool running in each process, so the code executing here will* NOT be running in our main thread like most other things -- so,* to update the UI, we need to use a Handler to hop over there.*/public void valueChanged(int value) {mHandler.sendMessage(mHandler.obtainMessage(BUMP_MSG, value, 0));}};private static final int BUMP_MSG = 1;private Handler mHandler = new Handler() {@Override public void handleMessage(Message msg) {switch (msg.what) {case BUMP_MSG:mCallbackText.setText("Received from service: " + msg.arg1);break;default:super.handleMessage(msg);}}}; }

    總結

    以上是生活随笔為你收集整理的Android Service 之 AIDL的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 虫族全黄h全肉污文 | 中文在线一区 | 国产六区| 一区二区三区在线观看免费视频 | 嫩草免费视频 | 亚洲国产视频一区二区 | 日韩一区二区三区免费在线观看 | 国产视频1区| 成人宗合网 | 一级伦理农村妇女愉情 | 福利视频在线看 | 欧美一性一交 | 日日草草| 欧美一级录像 | 成人精品二区 | 日韩有码一区二区三区 | 国产成人传媒 | 一级做a爰片久久毛片潮喷 天天透天天干 | 波多野结衣在线观看视频 | 男女吻胸做爰摸下身 | 亚洲伦乱| 丝袜 亚洲 另类 国产 制服 | 亚洲aaaa级特黄毛片 | 国产成人一区二区在线 | 一区二区三区四区高清视频 | 黄色福利视频网站 | 中文字幕岛国 | 波多野结衣一二三区 | 天天综合网天天综合 | 正在播放老肥熟妇露脸 | 日本免费色| 女人性做爰69片免费看 | 亚洲福利视频网 | 国产51精品 | 亚洲黄色在线观看视频 | 成年人午夜影院 | 高清日韩 | 91免费进入| 欧美另类xxx | 日韩美女视频一区二区 | 国产91av在线 | 韩国av一区二区三区 | 欧美囗交做爰视频 | 国产一级大片 | 日日草草| 日本午夜电影网站 | 日韩一区在线观看视频 | 亚洲玖玖玖 | 欧美三级在线播放 | 国产美女精品一区二区三区 | 夜色在线视频 | 理论片大全免费理伦片 | 国产一级三级 | 丁香六月在线 | 亚洲午夜一区二区三区 | 国产999| 公肉吊粗大爽色翁浪妇视频 | 性色欲网站人妻丰满中文久久不卡 | 99re6在线观看 | 福利视频网站 | 欧美色视频一区二区三区 | 久久成年人 | 欧美日韩精品一区二区在线观看 | 黄色片女人| 欧美aaaaaa| 扶她futa粗大做到怀孕 | 就爱操av | 特大黑人巨交吊性xxxx视频 | 欧洲av无码放荡人妇网站 | 亚洲av成人无码网天堂 | 精品乱人伦一区二区三区 | 天天射天天射天天射 | av网站大全在线 | 尤物在线观看 | 无码久久av一区二区三区 | 成人深夜视频在线观看 | 国产乱码久久久久 | 永久免费未满蜜桃 | 999久久久久久久久6666 | 欧美一级片在线免费观看 | 欧美熟女一区二区 | 超碰不卡 | 少妇一级淫片免费 | 97操操| 亚洲一区免费视频 | 国产成人精品一区二区三区无码熬 | 中文字幕一区二区人妻电影 | 夜夜嗨av一区二区三区网页 | 强行糟蹋人妻hd中文字幕 | 在线一区二区三区 | 一区二区亚洲精品 | 欧美一区二区三区免 | 吊视频一区二区三区 | 国产精品免费精品一区 | 99在线免费观看视频 | 69国产在线| 极品在线播放 | 九九视频免费在线观看 | 91美女视频网站 |