AIDL實現跨APP通訊(雙向通訊)
阿新 • • 發佈:2019-01-28
某天,接到了一人任務要在兩個app互相傳遞一些訊息,上網查了以後發現有幾種方式。第一是廣播、第二是AIDL,由於初出茅廬全不會就選擇了AIDL。。。下面簡單粗暴的開始貼程式碼好了。也是得到了網上的一些借鑑,若有雷同,嗯你懂的。
1.我們需要先建立AIDL檔案。值得一提的是,我們要在main下建立一個專門用來放AIDL檔案的包。非常重要!
其中,AIDLClient.aidl是客戶端使用的介面,AIDLService是伺服器所用的介面,Info是我們要傳的自定義實體類。客戶端就是想要主動給另一個app傳送資訊的一端,伺服器就是接收資訊並可以返回資訊的一端。下面來看看最簡單的AIDL裡面該怎麼寫。
(1)AIDLClient.aidl
<pre style="font-family: 宋體; font-size: 9pt; background-color: rgb(255, 255, 255);"><pre name="code" class="java">// AIDLClient.aidl package AIDL; // Declare any non-default types here with import statements interface AIDLClient { /** * 接收來自另一個app返回的資訊 */ void receiveByServer(String message); }
(2)AIDLClient.aidl
package AIDL;
// Declare any non-default types here with import statements
import AIDL.AIDLClient;
import AIDL.AIDLService;
interface AIDLService {
/**
* 接收來自客戶端發來的資訊
* @param info 實體類
*/
Info getServerdanceInfo(in Info info);
}
在客戶端給伺服器傳送請求後,伺服器會返回一個Info型別的實體。
(3)Info.aidl
// Info.aidl
package AIDL;
parcelable Info;
在Info中我們要使用我們自己寫的實體類型別,而不是用基本型別。
(4)Info
public class Info implements Parcelable {
private String message;
我們實體類中其實只有一個String型別,當然也可以有多個自己設定的型別,但是一定要使用AIDL中支援的幾個基本型別。剩下的就自動生成出get/set等就可以了,記得多寫一個預設建構函式。
2.在客戶端app中我們要實現點選按鈕,傳送訊息並將伺服器返回的訊息顯示著Textview中。
<pre name="code" class="java">public class MainActivity extends AppCompatActivity {
public static final String TAG = "MainActivity";
private static final String BIND_ACTION = "AIDL.service";
private Button button;
private TextView textView;
private AIDLService aidlServce;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
}
private void init(){
button = (Button)findViewById(R.id.sendAIDL);
textView = (TextView)findViewById(R.id.receive);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//繫結服務
getServiceConnect();
}
});
}
private void getServiceConnect(){
Intent it = new Intent();
it.setAction(BIND_ACTION);
it.setPackage("com.example.zjl.aidlservice_demo");
startService(it);
bindService(it, serviceConnection,BIND_AUTO_CREATE);
}
ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
Log.d(TAG,"onServiceDisconnected");
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.d(TAG,"onServiceConnected");
//獲取服務端傳過來的IBinder物件,通過該物件呼叫服務端的方法
aidlServce = AIDLService.Stub.asInterface(service);
if (aidlServce != null){
handlerInfo();
}
}
};
private void handlerInfo(){
Info mInfo = new Info();
mInfo.setMessage("腫麼可以次兔兔");
try {
Info serverInfo = new Info();
//呼叫服務端的方法
serverInfo = aidlServce.getServerInfo(mInfo,mClient);
unbindService(serviceConnection);
}catch (RemoteException e){
e.printStackTrace();
}
}
AIDLClient.Stub mClient = new AIDLClient.Stub()
{
//客戶端回撥方法的具體實現
@Override
public void receiveByServer(String param) throws RemoteException {
textView.setText(param);
}
};
}
這裡需要注意的是,在用Intent繫結服務的時候在5.0以後需要對package進行設定,否則會報錯。setPackage裡的引數為伺服器端的包名。XML就倆控制元件,一個button一個Textview就不寫了。
3.在伺服器中需要把AIDL連同包一起復制到main下同客戶端一樣。build後會自動生成java檔案,否則使用不了。
4.在服務端寫一個service用於接收來自客戶端的請求。
public class service extends Service {
public static final String TAG = "DanceAIDLService";
private AIDLClient aidlClient;
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
/**
* 建立服務
*/
@Override
public void onCreate()
{
super.onCreate();
}
/**
* 銷燬服務
*/
@Override
public void onDestroy()
{
super.onDestroy();
}
/**
* 啟動服務
*/
@Override
public void onStart(Intent intent, int startId)
{
super.onStart(intent, startId);
}
/**
* 解綁服務
*/
@Override
public boolean onUnbind(Intent intent)
{
aidlClient = null;
return super.onUnbind(intent);
}
//處理來自客戶端的訊息
AIDLService.Stub mBinder = new AIDLService.Stub() {
@Override
public Info getServerInfo(Info info, AIDLClient client) throws RemoteException {
aidlClient = client;
aidlClient.receiveByServer("收到來自客戶端的訊息:"+info.getMessage());
Log.d(TAG,info.getMessage()+" ");
Info newInfo = new Info();
newInfo.setMessage(info.getMessage());
return newInfo;
}
};
}
我們這把從客戶端發過來的資訊加了幾個字又返了回去。並且配置service。
<service
android:name=".service"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="AIDL.service"></action>
</intent-filter>
</service>
5.最後,還需要在build.gradle中新增用於區分aidl和java的命令。解除安裝Android括號內就可以。
sourceSets{
main{
java.srcDirs = ['src/main/java', 'src/main/aidl']
}
}
怎麼樣是不是好簡單,但是AIDL那些檔案真的很容易出錯誤哦,所以在第一次寫的時候可能會總也調不好,有點耐心慢慢調吧~~