Android通信のIPC-AIDL
7975 ワード
一例を用いて説明すると、まずクライアントがサービス側を呼び出す方法で書籍を追加し、その後、サービス側は5秒ごとに自分で新しい書籍を追加し、クライアントに通知する.
サービス側
クライアントに露出したこのインタフェースをこのAIDLファイルに宣言するAIDLファイルを作成し、まずクライアントの接続要求を傍受するためのServiceを作成し、このAIDLを実現すればよい.1.AIDLファイルを作成し、必要なメソッドを宣言します.以下に4つのメソッドを宣言します.中にはBookという類が使われているので、ガイドバッグを覚えておく必要があります.タイムリーに1つのバッグの下でガイドする必要があります.
リスニングを作成します.
2.サービスの作成
クライアント
サービス側のサービスをバインドし、サービス側から返されるBinderオブジェクトをAIDLインタフェースが属するタイプに変換することで、AIDLでメソッドを呼び出すことができます.
この時点でリモート・サービスは誰でも接続できるので、権限認証を行い、Mainfestファイルで権限をカスタマイズします.
サービスのonBindメソッドを変更し、
サービス側
クライアントに露出したこのインタフェースをこのAIDLファイルに宣言するAIDLファイルを作成し、まずクライアントの接続要求を傍受するためのServiceを作成し、このAIDLを実現すればよい.1.AIDLファイルを作成し、必要なメソッドを宣言します.以下に4つのメソッドを宣言します.中にはBookという類が使われているので、ガイドバッグを覚えておく必要があります.タイムリーに1つのバッグの下でガイドする必要があります.
// IBookManager.aidl
package com.demo.nick.ipcstudy;
// Declare any non-default types here with import statements
import com.demo.nick.ipcstudy.Book;
import com.demo.nick.ipcstudy.IOnNewBookArrivedListener;
interface IBookManager {
/**
* Demonstrates some basic types that you can use as parameters
* and return values in AIDL.
*/
List getBookList();
void addBook(in Book book);
void registerListener(IOnNewBookArrivedListener listener);
void unregisterListener(IOnNewBookArrivedListener listener);
}
リスニングを作成します.
package com.demo.nick.ipcstudy;
// Declare any non-default types here with import statements
import com.demo.nick.ipcstudy.Book;
interface IOnNewBookArrivedListener {
void onNewBookArrived(in Book book);
}
2.サービスの作成
public class BookManagerService extends Service {
private static final String TAG = "BookManagerService";
private CopyOnWriteArrayList mBookList = new CopyOnWriteArrayList<>();//
// beginBroadcast finishBroadcast
private RemoteCallbackList mListenerList=new RemoteCallbackList<>();
private AtomicBoolean mIsServiceDestoryed = new AtomicBoolean(false);//
// private CopyOnWriteArrayList mListenerList = new CopyOnWriteArrayList<>();
// AIDL
private Binder mBinder = new IBookManager.Stub() {
@Override
public List getBookList() throws RemoteException {
return mBookList;
}
@Override
public void addBook(Book book) throws RemoteException {
mBookList.add(book);
}
@Override
public void registerListener(IOnNewBookArrivedListener listener) throws RemoteException {
// if (!mListenerList.contains(listener)) {
// mListenerList.add(listener);
// }else {
// Log.e(TAG, "already exists: " );
// }
mListenerList.register(listener);
int a=mListenerList.beginBroadcast();
Log.e(TAG, " "+a );
mListenerList.finishBroadcast();
// Log.e(TAG, "registerListener : "+mListenerList.size());
}
@Override
public void unregisterListener(IOnNewBookArrivedListener listener) throws RemoteException {
// if(mListenerList.contains(listener)){
// mListenerList.remove(listener);
// Log.e(TAG, " : " );
// }else {
// Log.e(TAG, " : " );
// }
// Log.e(TAG, " "+mListenerList.size() );
// }
mListenerList.unregister(listener);
int a=mListenerList.beginBroadcast();
Log.e(TAG, " "+a );
mListenerList.finishBroadcast();
}
};
@Override
public void onCreate() {
super.onCreate();
mBookList.add(new Book(1, "android"));
mBookList.add(new Book(2, "ios"));
new Thread(new ServiceWorker()).start();
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
@Override
public void onDestroy() {
mIsServiceDestoryed.set(true);
super.onDestroy();
}
private void onNewBookArrived(Book book) throws RemoteException {
mBookList.add(book);
final int N=mListenerList.beginBroadcast();
for (int i=0;i
クライアント
サービス側のサービスをバインドし、サービス側から返されるBinderオブジェクトをAIDLインタフェースが属するタイプに変換することで、AIDLでメソッドを呼び出すことができます.
public class BookManagerAty extends AppCompatActivity {
private static final String TAG = "BookManagerAty";
private static final int MESSAGE_NEW_BOOK_ARRIVED=1;
private IBookManager mRemoteBookManager;
private Handler mHandler=new Handler(){
@Override
public void handleMessage(Message msg) {
switch (msg.what){
case MESSAGE_NEW_BOOK_ARRIVED:
Log.e(TAG, "new BOOK: "+msg.obj );
break;
default:
super.handleMessage(msg);
}
}
};
private ServiceConnection mConnection=new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
IBookManager bookManager=IBookManager.Stub.asInterface(service);
try {
mRemoteBookManager=bookManager;
List list=bookManager.getBookList();
Log.e(TAG, "onServiceConnected: "+list.getClass().getCanonicalName());
Log.e(TAG, "onServiceConnected: "+list.toString() );
Book book=new Book(3,"java");
bookManager.addBook(book);
List newList=bookManager.getBookList();
Log.e(TAG, "onServiceConnected: "+newList.toString() );
bookManager.registerListener(mOnNewBookArrivedLisener);//
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
mRemoteBookManager=null;
Log.e(TAG, "onServiceDisconnected: " );
}
};
private IOnNewBookArrivedListener mOnNewBookArrivedLisener=new IOnNewBookArrivedListener.Stub() {
@Override
public void onNewBookArrived(Book book) throws RemoteException {
mHandler.obtainMessage(MESSAGE_NEW_BOOK_ARRIVED,book).sendToTarget();
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_book_manager_aty);
Intent intent=new Intent(this, BookManagerService.class);
bindService(intent,mConnection, Context.BIND_AUTO_CREATE);
}
@Override
protected void onDestroy() {
if (mRemoteBookManager!=null&&mRemoteBookManager.asBinder().isBinderAlive()){
Log.e(TAG, "onDestroy: "+mOnNewBookArrivedLisener );
try {
mRemoteBookManager.unregisterListener(mOnNewBookArrivedLisener);//
} catch (RemoteException e) {
e.printStackTrace();
}
}
unbindService(mConnection);
super.onDestroy();
}
}
この時点でリモート・サービスは誰でも接続できるので、権限認証を行い、Mainfestファイルで権限をカスタマイズします.
サービスのonBindメソッドを変更し、
@Nullable
@Override
public IBinder onBind(Intent intent) {
// , , .
int check=checkCallingOrSelfPermission("com.demo.nick.ipcstudy.permission.TEST");
if (check== PackageManager.PERMISSION_DENIED){
// , 。
return null;
}
return mBinder;
}