分两个app -- 客户端为:jinc1application、服务端为:jinc2application
这是 Android 中最常用的通讯方式,主要用于启动 Activity、Service 等
jinc1application 中的代码
//通过budle传递数据,可以携带序列化数据
Bundle bundle = new Bundle();
bundle.putInt("intextra", 1);
bundle.putString("stringextra", "测试数据");
Intent intent = new Intent();
//制定要打开的程序的包名(必须写全包名,不然会报错)和地址(activity名)
intent.setComponent(new ComponentName("com.example.jinc2application",
"com.example.jinc2application.MainActivity"));//要启动的目标包名和包名+类名
intent.putExtras(bundle);
try{
startActivity(intent);
}catch(Exception e){
Log.e("TAG","没有找到对应文件---------------");
}
jinc2application 中的代码
public class MainActivity extends AppCompatActivity {
@SuppressLint("MissingInflatedId")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 获取意图对象
Intent intent = getIntent();
//获取传递的值
String stringextra= intent.getStringExtra("stringextra");
int intextra= intent.getIntExtra("intextra",0);
//打印获取的数据
Log.e("TAG","stringextra---------------"+stringextra);
Log.e("TAG","intextra---------------"+intextra);
}
}
这是基于 Binder 的一种轻量级的 IPC 机制,主要用于跨进程发送 Message。
jinc1application 中的代码
<Button
android:onClick="btn7"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Messenger"/>
private Messenger mService;
@SuppressLint("HandlerLeak")
private Handler mReplyHandler = new Handler(){
@Override
public void handleMessage(@NonNull Message msg) {
switch (msg.what) {
case 22:
Log.e("TAG","-------"+msg.getData().get("msg").toString());
break;
}
}
};
private Messenger mClientMessenger= new Messenger(mReplyHandler);
private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
mService = new Messenger(iBinder);
//创建消息,通过Bundle传递数据
Message message = Message.obtain(null, 1111);
Bundle bundle = new Bundle();
bundle.putString("msg", "你好我是客户端的数据");
message.setData(bundle);
//如果需要服务器返回消息,则需要将客户端的Messenger对象传递给服务端,如果不需要返回消息,则不用加这一句
message.replyTo = mClientMessenger;
try {
//向服务端发送消息
mService.send(message);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
}
};
public void btn7(View view) {
Intent intent = new Intent();
intent.setAction("com.example.jinc2application.MyService");
intent.addCategory(Intent.CATEGORY_DEFAULT);
PackageManager pm = getPackageManager();
ResolveInfo info = pm.resolveService(intent, 0);
if(info != null){
//如果ResolveInfo不为空,说明我们能通过上面隐式的Intent找到对应的Service
//我们可以获取将要启动的Service的package信息以及类型
String packageName = info.serviceInfo.packageName;
String serviceNmae = info.serviceInfo.name;
ComponentName componentName = new ComponentName(packageName, serviceNmae);
intent.setComponent(componentName);
try{
bindService(intent,mConnection,BIND_AUTO_CREATE);
}catch(Exception e){
e.printStackTrace();
Log.e("DemoLog", e.getMessage());
}
}
}
jinc2application 中的代码
public class MyService extends Service {
/**
* 处理来自客户端的消息,并用于构建Messenger
*/
private static class MessengerHandler extends Handler {
@Override
public void handleMessage(Message message) {
switch (message.what) {
//客户端建立连接
case 1111://MESSAGE_FROM_CLIENT
Log.e("TAG", "-------" + message.getData().getString("msg"));
//向客户端回传消息
Message msg = Message.obtain(null, 22);//MESSAGE_FROM_SERVICE
Bundle b = new Bundle();
b.putString("msg","你好我是服务端的数据");
msg.setData(b);
try {
//如果服务端需要回复客户端,则需要拿到客户端携带过来的Messenger 对象(即msg.replyTo),通过msg.replyTo.send方法给客户端发送信息
message.replyTo.send(msg);
} catch(RemoteException e){
e.printStackTrace();
}
break;
default:
super.handleMessage(message);
break;
}
}
}
/**
* 构建Messenger对象
*/
private final Messenger mMessenger = new Messenger(new MessengerHandler());
@Nullable
@Override
public IBinder onBind(Intent intent) {
return mMessenger.getBinder();
}
}
<service android:name=".MyService"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.example.jinc2application.MyService"></action>
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</service>
点击参考传递对象(类)的例子
这是 Android 提供的一种 IPC 机制,主要用于实现跨进程的接口调用。
AIDL 是Android的进程间通信(IPC)比较常用的一种方式,AIDL 是 Android Interface Definition Language 的缩写,即Android接口定义语言。
1、AIDL优点:
1.进程间通信不止有AIDL,我们还有其他选择,例如 BroadcastReceiver , Messenger 等,但是 BroadcastReceiver 存在占用的系统资源比较多和存在延迟问题,在频繁的跨进程通信时是无法满足需求的;Messenger 进行跨进程通信时请求队列是同步进行的,无法并发执行,不能进行多进程通信,局限性比加大,这个时候就需要使用 AIDL 了。
2.编译器通过*.aidl文件的描述信息生成符合通信协议的Java代码,我们无需自己去写这段繁杂的代码,只需要在需要的时候调用即可,通过这种方式我们就可以完成进程间的通信工作。
下面是传 String值为例
2、使用步骤详情
jinc2application 中的代码
AIDL的底层是基于Binder实现的,而Binder机制也是一种请求-响应式的通信模型,请求方一般称为Client,响应方称为Server。
Rebuild Project
public class MyAIDLService extends Service {
@Nullable
@Override
public IBinder onBind(Intent intent) {
return myBinder;
}
private IBinder myBinder=new IMyAidlInterface.Stub() {
@Override
public String getMessages() throws RemoteException {
return "返回测试数据-------------";
}
};
}
jinc1application 中的代码
注意
:客户端和服务端AIDL的文件和路径要一致。 <Button
android:onClick="btn8"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="AIDL"/>
//AIDL
private static IMyAidlInterface sIAidlServiceInterface;
public void btn8(View view) {
Intent intent = new Intent();
intent.setAction("com.example.jinc2application.MyAIDLService");
intent.setPackage("com.example.jinc2application");//包名
bindService(intent, serviceConnection, Service.BIND_AUTO_CREATE);
}
private ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
sIAidlServiceInterface = IMyAidlInterface.Stub.asInterface(service);
try {
String message = sIAidlServiceInterface.getMessages();
Log.e("TAG", "the message:" + message);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
Log.e("TAG", "name:" + name);
}
};
这是 Android 中的一种广播机制,可以用于实现跨进程的事件通知。
两个app间发送广播和正常发送广播其实差不多
在jinc1application中发广播,在jinc2application中接受广播
jinc2application 中的代码
public class MyBoradCast extends BroadcastReceiver {
public static final String BROADCAST_ACTION_TEST = "com.example.jinc2application.MyBoradCast";
@Override
public void onReceive(Context context, Intent intent) {
if (BROADCAST_ACTION_TEST .equals(intent.getAction())){
Bundle bundle = intent.getExtras();
String test = (String) bundle.get("text");
Log.e("测试接收到广播:",test );
}
}
}
public class MainActivity extends AppCompatActivity {
private MyBoradCast myReceiver;
@SuppressLint("MissingInflatedId")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("com.cn.broadcast.test.ACTION");
myReceiver = new MyBoradCast();
registerReceiver(myReceiver, intentFilter);
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(myReceiver);
}
}
jinc1application 中的代码
// 通过Intent类的构造方法指定广播的ID
Intent intent = new Intent("com.example.jinc2application.MyBoradCast" );//测试接收到广播
// 将要广播的数据添加到Intent对象中
intent.putExtra("text", "测试发送广播");
// 发送广播
sendBroadcast(intent);
<Button
android:onClick="btn11"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="文件"/>
public void btn11(View view) {
// 在你的 Activity 中,查询是否有权限
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
// Permission is not granted
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
111);
}else {//已经授权,写入文件数据
try {
File file = new File(Environment.getExternalStorageDirectory(), "ceshi.txt");
FileWriter writer = new FileWriter(file);
writer.append("我是测试数据");
writer.flush();
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
@SuppressLint("MissingSuperCall")
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case 111: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted 已授予许可
try {
File file = new File(Environment.getExternalStorageDirectory(), "ceshi.txt");
FileWriter writer = new FileWriter(file);
writer.append("我是测试数据");
writer.flush();
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
} else { // permission denied 权限被拒绝
}
return;
}
}
}
public class MainActivity extends AppCompatActivity {
@SuppressLint("MissingInflatedId")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 在你的 Activity 中
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
// Permission is not granted
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
111);
}else {
//获取文件内容
try {
File file = new File(Environment.getExternalStorageDirectory(), "ceshi.txt");
BufferedReader reader = new BufferedReader(new FileReader(file));
String line = reader.readLine();
while (line != null) {
Log.e("App2", line);
line = reader.readLine();
}
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
@SuppressLint("MissingSuperCall")
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case 111: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted 已授予许可
try {
File file = new File(Environment.getExternalStorageDirectory(), "ceshi.txt");
BufferedReader reader = new BufferedReader(new FileReader(file));
String line = reader.readLine();
while (line != null) {
Log.e("App2", line);
line = reader.readLine();
}
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
} else {
// permission denied 权限被拒绝
}
return;
}
}
}
}