Android 进程与进程之间的通讯 详解及实现步骤 -- 两个app实现

这篇具有很好参考价值的文章主要介绍了Android 进程与进程之间的通讯 详解及实现步骤 -- 两个app实现。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


分两个app -- 客户端为:jinc1application、服务端为:jinc2application

Android 进程与进程之间的通讯 详解及实现步骤 -- 两个app实现,android studio

一、Intent

这是 Android 中最常用的通讯方式,主要用于启动 Activity、Service 等

jinc1application 中的代码

  • 1、 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","没有找到对应文件---------------");
        }
  • 注意:要启动的目标包名和包名+类名如下:
    Android 进程与进程之间的通讯 详解及实现步骤 -- 两个app实现,android studio

jinc2application 中的代码

  • 2、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);
    }
}

二、Messenger

这是基于 Binder 的一种轻量级的 IPC 机制,主要用于跨进程发送 Message。

jinc1application 中的代码

  • 1、jinc1application 的代码如下:给一个点击事件
 <Button
        android:onClick="btn7"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Messenger"/>
  • MainActivity 的代码实现
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 中的代码

  • 2、jinc2application代码如下: 创建 MyService
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();
    }
}
  • 3、在清单文件中注册
<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>

三、AIDL

点击参考传递对象(类)的例子

这是 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。

  • 1、src\main 目录 右键new一个AIDL文件。
    Android 进程与进程之间的通讯 详解及实现步骤 -- 两个app实现,android studio
  • 2、输入自定义AIDL名字,点击OK,即可创建出AIDL接口文件,文件中会默认生出一个basicTypes方法,该方法描述了AIDL中可以使用的基本类型(int, long, boolean, float, double, String)。下面是以String为例:
    Android 进程与进程之间的通讯 详解及实现步骤 -- 两个app实现,android studio
  • 3、定义后需要 Rebuild Project
    Android 进程与进程之间的通讯 详解及实现步骤 -- 两个app实现,android studio
  • 4、创建一个实现类,继承刚才创建的AIDL的名称里的Stub类,并实现接口方法。
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 "返回测试数据-------------";
        }
    };
}
Android 进程与进程之间的通讯 详解及实现步骤 -- 两个app实现,android studio
  • 5、在清单文件里配置service,android:exported=“true”,必须配置成true,才能被其他app调用
    Android 进程与进程之间的通讯 详解及实现步骤 -- 两个app实现,android studio

jinc1application 中的代码

  • 6、将服务端AIDL文件拷贝到客户端相同包的位置,然后Rebuild Project 重新编译
    注意:客户端和服务端AIDL的文件和路径要一致。
    Android 进程与进程之间的通讯 详解及实现步骤 -- 两个app实现,android studio
  • 7、activity_main.xml 写一个点击事件
  <Button
        android:onClick="btn8"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="AIDL"/>
  • 8、MainActivity 里面的处理
 //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 中的代码

  • 1、在 jinc2application 创建一个java类继承BroadcastReceiver类,用来在 onReceive()方法中处理获得的广播。
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 );
        }
    }
}
  • 2、在java代码中动态注册,代码如下:
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 中的代码

  • 3、在 jinc1application 在java代码中发送广播,发送的action与jinc2application中接受到的action要一致,代码如下:
 // 通过Intent类的构造方法指定广播的ID
        Intent intent = new Intent("com.example.jinc2application.MyBoradCast" );//测试接收到广播
        // 将要广播的数据添加到Intent对象中
        intent.putExtra("text", "测试发送广播");
        // 发送广播
        sendBroadcast(intent);

五、文件

  • jinc1application 中的代码
    Android 进程与进程之间的通讯 详解及实现步骤 -- 两个app实现,android studio

  • 页面给个点击事件触发:点击去查询是否有存储权限,如果已授权,直接存数据,否则去获取权限页面,手动赋予文章来源地址https://www.toymoban.com/news/detail-549352.html

    <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;
            }
        }
    }
  • jinc2application 中的代码
    Android 进程与进程之间的通讯 详解及实现步骤 -- 两个app实现,android studio
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;
            }
        }
    }
}

到了这里,关于Android 进程与进程之间的通讯 详解及实现步骤 -- 两个app实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 基于android的即时通讯APP 聊天APP

    该项目是基于Android 的聊天APP系统,该APP包含前台,后台管理系统,前台包含用户通讯录,用户详情,用户聊天服务,用户二维码,发现功能,发现详情 , 个人中心, 个人信息, 编辑信息,上传头像,注册,登录,退出 等操作 。后台包含 系统管理,用户管理,聊天内容管理,聊天

    2024年02月02日
    浏览(51)
  • 蓝牙聊天App设计3:Android Studio制作蓝牙聊天通讯软件(完结,蓝牙连接聊天,结合生活情景进行蓝牙通信的通俗讲解,以及代码功能实现,内容详细,讲解通俗易懂)

    前言:蓝牙聊天App设计全部有三篇文章(一、UI界面设计,二、蓝牙搜索配对连接实现,三、蓝牙连接聊天),这篇文章是:三、蓝牙连接聊天。 课程1:Android Studio小白安装教程,以及第一个Android项目案例“Hello World”的调试运行 课程2:蓝牙聊天App设计1:Android Studio制作蓝

    2024年02月12日
    浏览(44)
  • Android不同APP之间共享数据的方式

    今天给大家介绍三种不同APP之间共享数据的方式 第一种:使用SharePreference 使用SharePreference共享数据 第二种:使用ContentProvider, 这个就不仔细讲了,大家看看其他文章吧 第三种:sharedUserId 通过SharedUser id,拥有同一个User id的多个APK可以配置成运行在同一个进程中.所以默认就是

    2024年02月10日
    浏览(52)
  • Java 实现两个日期之间相差多少天

    Java 实现两个日期之间相差多少天 运行结果:

    2024年02月15日
    浏览(49)
  • Windows 共享内存实现进程间通讯

    在 windows 中 使用 CreateFileMappingW , MapViewOfFile 函数实现共享内存的创建和挂载。 使用了 CreateEvent , CreateMutex 函数实现进程间的互斥通讯 具体介绍: MSDN CreateFileMappingW 具体介绍可以看上方的官方文档这里不过多赘述,不过有一点需要提一下。 CreateFileMapping函数有两种 1.CreateFi

    2024年02月16日
    浏览(47)
  • (二)MQTT+阿里云实现两个设备之间的通信。

    MQTT+阿里云的使用 讲了如何使用阿里云,实现云端和客户端之间的通信,这篇就说客户端和客户端之间如何通信。 我们创建了一个名为:stm32_to_client的解析器: 回到云产品流传页面,创建数据源: 我这里创建了一个名为:DateSrc_stm32_to_client的数据源,然后点击添加topic: 按照

    2023年04月09日
    浏览(32)
  • 如何实现两个电脑之间通过以太网(网线)实现文件互传

    本帖目的:介绍如何通过以太网(网线)连接两台电脑,通过文件夹共享的方式,实现两台电脑之间的文件互传。 本帖以笔者实际工作上遇到的场景为例进行介绍,两台电脑分别是一台办公台式机和一台笔记本调试机,目的是将台式机上的某个文件发送到调试机上。受限于公

    2024年02月22日
    浏览(42)
  • 如果elasticsearch要实现在大于两个索引之间关联查询怎么实现

    Elasticsearch可以通过多种方式在多个索引之间进行关联查询。 一种常用的方法是使用关联查询(join query), 这需要在索引和类型中使用 _join 字段来存储关联关系。 另一种方法是使用查询时连接(query time join),使用过滤器上下文来连接不同索引中的文档。 还可以使用 Elasticsearch 的聚

    2024年02月08日
    浏览(65)
  • Java实现获取两个时间节点之间的日期、月份、年份列表

    我们在做一个需求的时候需要后端返回一个选中时间内的时间日期、月份、年份列表: 如:我想查询2024-01-01到2024-01-20这个时间里面的所有日期。 下面来看看代码 调用如下:

    2024年01月23日
    浏览(51)
  • 计算两个或多个向量之间的相关性(Matlab 实现)

    本文首次在公众号【零妖阁】上发表,为了方便阅读和分享,我们将在其他平台进行自动同步。由于不同平台的排版格式可能存在差异,为了避免影响阅读体验,建议如有排版问题,可前往公众号查看原文。感谢您的阅读和支持! 两个随机变量 x x x 、 y y y 的 Pearson 线性相关

    2024年02月04日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包