Androidの最近の研究プロセス間通信、芸術的探査の発展を参照して、AIDLを使用するが、実際にもいくつかの問題、プロセスの特別な注意が発生し、よくある質問、ツールのAndroid Studioを使用
1. AIDLを書かれたサーバファイルは
、新しいクリックAIDLインターフェイスファイルを作成
IMyAidlInterface.aidlファイルを生成し、ファイル名は、独自に変更することができます
package com.example.android_7_test;
// Declare any non-default types here with import statements
import com.example.android_7_test.Book;
interface IMyAidlInterface {
/**
* Demonstrates some basic types that you can use as parameters
* and return values in AIDL.
* 在接口文件中定义 服务端提供的方法 供客户端调用 ,下面的setBook是我测试的方法
*
*/
void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
double aDouble, String aString);
/**
1.定义的方法不能有修饰符
2.不能有方法体
3.除了基本数据类型,要加上方向参数 in 输入性(作为参数传入) out 输出型(返回值) inout
*/
boolean setBook(in Book book);
}
そしてブック(parcelableインターフェイスを実装するエンティティクラス)のテストのようなエンティティは、同じパッケージにBook.aidlを作成中に、カスタムエンティティクラスは、あなたが新しいをクリックすることができ、同じ名前のAIDLファイルを作成する必要があります、あります - 「ファイル - 」適切な参照上記のファイル名の拡張子マップ.aidl、
package com.example.android_7_test;
/**
注明 parcelable + 自定义类名
*/
parcelable Book;
注:3クラスのパッケージ名を同じにする必要があり、それが自動的にパッケージ名を生成することが可能である。AIDL .XXXを、間違っている可能性があり、それが削除されますが、関連するエンティティクラスにも明白に組み込まIMyAidlInterfaceインターフェース、参照コードのトップ
エンティティクラスと2つのAIDLは、ディレクトリエンティティクラスにアクセスすることはできませんが、そこではありません同じパッケージに提出する必要はありませんが、移植のクライアントを容易にするためには、同じパッケージを置くことをお勧めしますが、これはJavaのクラスになりますあなたが設定を追加する必要があり、この時に、クラス参照を見つけるbuild.gradle
android{
sourceSets {
main {
manifest.srcFile 'src/main/AndroidManifest.xml'
java.srcDirs = ['src/main/java', 'src/main/aidl']
resources.srcDirs = ['src/main/java']
aidl.srcDirs = ['src/main/aidl']
res.srcDirs = ['src/main/res']
assets.srcDirs = ['src/main/assets']
}
}
}
2. javaファイルAIDLを生成するプロジェクトを同期
生成されたJavaファイルを見ることができ、「ソース- 」AIDL完了後のプロジェクトのディレクトリ構造のビルド-の下で、クリック同期プロジェクトを
サーバーがインターフェイスを実装3.
1.实现接口
2.重写onBind,返回binder对象
/**
这个是kotlin代码,可以自己改成java代码
*/
class MyService : Service() {
//实现接口,这里实现的是接口的内部stub类
val interfa = object : IMyAidlInterface.Stub() {
override fun setBook(book: Book?): Boolean {
//实现定义的方法,这里是发送一个toast
Handler(Looper.getMainLooper()).post({ Toast.makeText(applicationContext, "收到设置", Toast.LENGTH_SHORT).show() })
return true
}
override fun basicTypes(anInt: Int, aLong: Long, aBoolean: Boolean, aFloat: Float, aDouble: Double, aString: String?) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
}
override fun onBind(intent: Intent): IBinder {
//返回binder对象,不返回的话绑定服务无法成功
return interfa.asBinder()
}
}
マニフェストファイル4.登録サービス
<!--
process = ":remote" 这个表示在新的进程中运行
exported = "true" 这个标识是否可被外部程序调用,不设置的话外部程序绑定启动这个service会出现
java.lang.SecurityException: Not allowed to bind to service Intent
-->
<service
android:name=".MyService"
android:process=":remote"
android:exported="true"
></service>
5.同じパッケージにクライアントファイルのコピーを作成し
、ディレクトリ、ファイルおよびサーバー名パッケージに新しいパッケージを作成することができ、AIDLディレクトリを生成し、AIDLファイルを作成し、同じサーバであってもよいが、これは、生成されたパッケージ名と一致しないだろう合意
①同様に、このディレクトリのJavaのクラスファイルは、エンティティクラス帳にアクセスすることができない、または上記の構成build.gradleを実行するために!!!
②パッケージ名は、サーバーのパッケージ名と一致する必要があります!!!それ以外の場合は、間違ったインターフェイスに呼び出しがバインダーます
6.クライアントバインディング開始サービスは、関連するメソッドを呼び出します
/**
获取返回的binder对象
*/
IMyAidlInterface iMyAidlInterface = null;
private ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
iMyAidlInterface = IMyAidlInterface.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
Intent intent = new Intent();
/**
跨进程,无法使用Intent(this,xx.class)方法,可以使用下面的,通过包名和完整路径类名创建Intent
*/
intent.setClassName("com.example.android_7_test","com.example.android_7_test.MyService");
bindService(intent,serviceConnection,BIND_AUTO_CREATE);
}
背後にある通信の終了IMyAidlInterfaceオブジェクトメソッドによって定義されたサービスを呼び出すことができ、エラープローンは、上記の点に留意します。
読書のためのおかげで、間違っている場合は、私を修正してください。