(七)Android中AIDL的应用与理解

一、跨应用启动Service

Intent serviceIntent=new Intent();
serviceIntent.setComponent(new ComponentName("com.example.shiyanshi.startservicefromanotherapp","com.example.shiyanshi.startservicefromanotherapp.AppService"));
跨应用启动Service时,Android5.0以前可以调用隐式Intent(通过在Service设置过滤器intent-filte),Android5.0之后只允许显示Intent来启动。首先创建Intent,之后调用setComponent函数来设置组件,该函数需要一个ComponentName的对象,ComponentName第一个参数为包名,第二个参数为包中的服务类名。

二、跨应用绑定Service并进行通信

app模块中:

1.MainActivity.java

package com.example.shiyanshi.startservicefromoterapp;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;


public class MainActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);


startService(new Intent(this,MyService.class));
}


@Override
protected void onDestroy() {
super.onDestroy();

stopService(new Intent(this,MyService.class));
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();

//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}

return super.onOptionsItemSelected(item);
}
}

2.MyService.java

package com.example.shiyanshi.startservicefromoterapp;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;

public class MyService extends Service {
public MyService() {
}

private String data="default data";
private boolean flag;

@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
// throw new UnsupportedOperationException("Not yet implemented");

//返回的是AIDL中的接口,并且此处实现了接口函数的重定义
return new IAppRemoteServiceBinder.Stub() {
@Override
public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {

}

@Override
public void setData(String data) throws RemoteException {
MyService.this.data=data;
}
};

    }

@Override
public void onCreate() {
super.onCreate();
System.out.println("**********MyService onCreate************");
 

//该线程主要用于不断的输出该service种的数据data,data数据的值可以通过在anotherapp中调用setData函数进行设置,这样便实现了双方的通信



new Thread(){
@Override
public void run() {
super.run();
flag=true;
while (flag) {
System.out.println(data);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}

@Override
public void onDestroy() {
super.onDestroy();

System.out.println("***************MyService onDestroy********************");
flag=false;
}
}
//

不同的应用进行通信时需要创建aidl文件,并且在其中实现接口函数的定义

3.IAppRemoteServiceBinder.aidl

// IAppRemoteServiceBinder.aidl
package com.example.shiyanshi.startservicefromoterapp;

// Declare any non-default types here with import statements

interface IAppRemoteServiceBinder {
/**
* 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);

void setData(String data); //用于两个应用程序之间进行通信的接口函数

}
 
anotherapp中:

1.布局文件

<LinearLayout 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:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">

<TextView android:text="@string/hello_world" android:layout_width="wrap_content"
android:layout_height="wrap_content" />

<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="启动外部服务"
android:id="@+id/btnStartService"
android:layout_gravity="bottom" />

<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="关闭外部服务"
android:id="@+id/btnStopService"
android:layout_gravity="center_vertical" />

<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="绑定外部服务"
android:id="@+id/btnBindService" />

<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="解除绑定外部服务"
android:id="@+id/btnUnbindService" />

<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="同步数据到外部服务"
android:id="@+id/btnSyncDataToAppService" />
<EditText
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="**************"
android:id="@+id/editTextInput"/>

</LinearLayout>

 

2.MainActivity.java

package com.example.shiyanshi.anotherapp;

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.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.EditText;

import com.example.shiyanshi.startservicefromoterapp.IAppRemoteServiceBinder;


public class MainActivity extends Activity implements View.OnClickListener, ServiceConnection {

Intent serviceIntent;
private EditText editTextInput;
private IAppRemoteServiceBinder binder;


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

editTextInput=(EditText)findViewById(R.id.editTextInput);

findViewById(R.id.btnStartService).setOnClickListener(this);
findViewById(R.id.btnStopService).setOnClickListener(this);
findViewById(R.id.btnBindService).setOnClickListener(this);
findViewById(R.id.btnUnbindService).setOnClickListener(this);

findViewById(R.id.btnSyncDataToAppService).setOnClickListener(this);


serviceIntent=new Intent();
serviceIntent.setComponent(new ComponentName("com.example.shiyanshi.startservicefromoterapp","com.example.shiyanshi.startservicefromoterapp.MyService"));

}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();

//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}

return super.onOptionsItemSelected(item);
}

@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.btnStartService:
startService(serviceIntent);
break;
case R.id.btnStopService:
stopService(serviceIntent);
break;
case R.id.btnBindService:

bindService(serviceIntent,this, Context.BIND_AUTO_CREATE);

                break;
case R.id.btnUnbindService:
unbindService(this);
binder=null;
break;

case R.id.btnSyncDataToAppService:
if (binder!=null){
try {
binder.setData(editTextInput.getText().toString());
} catch (RemoteException e) {
e.printStackTrace();
}
}
break;

        }

}

@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
System.out.println("*******onServiceConnected*************");

//不能直接强制类型转换,因为两个类型处于不同的应用程序中
binder=IAppRemoteServiceBinder.Stub.asInterface(iBinder);

    }

@Override
public void onServiceDisconnected(ComponentName componentName) {

}
}
 

3.文件目录结构,将在App模块中创建的aidl文件复制到了anotherapp中,首先穿件aidl目录,然后在aidl目录中创建app中的程序包(com.example.shiyanshi.startservicefromoterapp),之后将app中的IAppRemoteServiceBinder.aidl文件复制到该程序包

image

 
原文地址:https://www.cnblogs.com/ql698214/p/5118721.html