AIDL Service,跨进程调用Services
生活随笔
收集整理的這篇文章主要介紹了
AIDL Service,跨进程调用Services
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
一、AIDL Service簡介
Android系統(tǒng)中,各個應(yīng)用都運行在自己的進程中,進程之間一般無法直接進行通信,為了實現(xiàn)進程通信,Android提供了AIDL Service;
二、與本地Service不同?
本地Service:直接把IBinder對象本身傳遞給客戶端的ServiceConnection的onServiceConnected方法的第二個參數(shù);?遠(yuǎn)程Service:只將IBinder對象的代理傳給客戶端的ServiceConnection的onServiceConnected方法的第二個參數(shù);?
三、AIDL文件
Android需要AIDL(Android Interface Definition Language)來定義遠(yuǎn)程接口,這種接口定義語言并不是一種真正的變成語言,只是定義兩個進程之間的通信接口;
與Java接口相似,但是存在如下幾點差異:
AIDL定義接口的源代碼必須以.aidl結(jié)尾; ?
AIDL用到的數(shù)據(jù)類型,除了基本類型、String、List、Map、CharSequence之外,其它類型全部都需要導(dǎo)包,即使它們在同一個包中也需要導(dǎo)包;
四、例子:
1. 創(chuàng)建AIDL文件,定義好的AIDL文件后,ADT工具會自動在gen目錄下生成一個AIDL.java接口,該類內(nèi)部包含一個Stub內(nèi)部類,實現(xiàn)了IBinder,AIDL里面的接口,這個Stub類會作為遠(yuǎn)程Service回調(diào)類:
IMyService.aidl package com.juno.serviceaidltest; import com.juno.serviceaidltest.Product; interface IMyService { String getValue(); Map getMap(in String country, in Product product); Product getProduct(); }
Product.aidl parcelable Product;
Product.java package com.juno.serviceaidltest; import android.os.Parcel; import android.os.Parcelable; public class Product implements Parcelable { private int id; private String name; private float price; public static final Parcelable.Creator<Product> CREATOR = new Parcelable.Creator<Product>() { public Product createFromParcel(Parcel in) { return new Product(in); } public Product[] newArray(int size) { return new Product[size]; } }; public Product() { } private Product(Parcel in) { readFromParcel(in); } @Override public int describeContents() { return 0; } public void readFromParcel(Parcel in) { id = in.readInt(); name = in.readString(); price = in.readFloat(); } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeInt(id); dest.writeString(name); dest.writeFloat(price); } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public float getPrice() { return price; } public void setPrice(float price) { this.price = price; } }
2. 將接口暴露給客戶端
MyService.java package com.juno.serviceaidltest; import java.util.HashMap; import java.util.Map; import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.os.RemoteException; public class MyService extends Service { /** * 繼承Stub,也就是實現(xiàn)了IMyService接口,并實現(xiàn)了IBinder接口 */ public class MyServiceImpl extends IMyService.Stub { @Override public String getValue() throws RemoteException { return "Test Value"; } @Override public Map<String, Object> getMap(String country, Product product) throws RemoteException { Map<String, Object> map = new HashMap<String, Object>(); map.put("country", country); map.put("id", product.getId()); map.put("name", product.getName()); map.put("price", product.getPrice()); map.put("product", product); return map; } @Override public Product getProduct() throws RemoteException { Product product = new Product(); product.setId(1234); product.setName("汽車"); product.setPrice(31000); return product; } } @Override public IBinder onBind(Intent intent) { /** * 返回MyServiceImpl對象,在綁定本地Service情況下,該MyServiceImpl會直接傳給客戶端的ServiceConnected對象的ServiceConnected()方法的第二個參數(shù);在綁定遠(yuǎn)程Service的情況下,只將MyServiceImpl對象的代理傳給客戶端的ServiceConnected對象的ServiceConnected()方法的第二個參數(shù) */ return new MyServiceImpl(); } }
3.? 在AndroidManifext.xml文件中配置該Service:
<service android:name=".MyService" > <intent-filter> <action android:name="com.juno.serviceaidltest.IService" /> </intent-filter> </service>
4. 在Activity里訪問 AIDLService,如果不在同一個App下面訪問,需要將Service端的AIDL文件復(fù)制到客戶端中,并在相同的包名下:
MainActivity.java package com.juno.serviceanotheraidltest; import android.app.Activity; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.os.Bundle; import android.os.IBinder; import android.os.RemoteException; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.TextView; import com.juno.serviceaidltest.IMyService; public class MainActivity extends Activity implements View.OnClickListener { private final static String ACTION = "com.juno.serviceaidltest.IService"; private IMyService myService = null; private Button mBtnInvokeAIDLService; private Button mBtnBindAIDLService; private TextView mTextView; private ServiceConnection mServiceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { //獲取遠(yuǎn)程Service的onBinder方法返回的對象代理 myService = IMyService.Stub.asInterface(service); mBtnInvokeAIDLService.setEnabled(true); try { Log.v("juno", myService.getValue()); } catch (RemoteException e) { e.printStackTrace(); } } @Override public void onServiceDisconnected(ComponentName name) { myService = null; } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); } private void initView() { mBtnInvokeAIDLService = (Button) findViewById(R.id.btnInvokeAIDLService); mBtnBindAIDLService = (Button) findViewById(R.id.btnBindAIDLService); mBtnInvokeAIDLService.setEnabled(false); mTextView = (TextView) findViewById(R.id.textView1); mBtnInvokeAIDLService.setOnClickListener(this); mBtnBindAIDLService.setOnClickListener(this); } @Override public void onClick(View view) { switch (view.getId()) { case R.id.btnBindAIDLService: //創(chuàng)建所需要綁定的Service的Intent,綁定遠(yuǎn)程的服務(wù) bindService(new Intent(ACTION), mServiceConnection, Context.BIND_AUTO_CREATE); break; case R.id.btnInvokeAIDLService: try { String s = myService.getValue(); s = "Product.id = " + myService.getProduct().getId() + "\n"; s += "Product.name = " + myService.getProduct().getName() + "\n"; s += "Product.price = " + myService.getProduct().getPrice() + "\n"; s += myService.getMap("China", myService.getProduct()).toString(); mTextView.setText(myService.asBinder().isBinderAlive() + " " + s); } catch (Exception e) { } break; } } @Override protected void onDestroy() { super.onDestroy(); if (myService != null) { //解除綁定 unbindService(mServiceConnection); } } }
布局文件
activity_main.xml <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity" > <TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/hello_world" /> <Button android:id="@+id/btnBindAIDLService" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/textView1" android:text="btnBindAIDLService" /> <Button android:id="@+id/btnInvokeAIDLService" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/btnBindAIDLService" android:text="btnInvokeAIDLService" /> </RelativeLayout>
總結(jié)
以上是生活随笔為你收集整理的AIDL Service,跨进程调用Services的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: nodeJs 操作数据库
- 下一篇: 数据库自学-SQL-四大SQL语句DDL