Android 跨进程通信

Android中常用的跨进程通信方法有以下几种:
Intent、Binder、AIDL、Messenger、ContentProvider。

Intent

可以通过Intent传递数据和消息,但是只能传递一些简单的数据类型,比如字符串、整数等。
示例:

  1. 从一个应用程序发送一个字符串到另一个应用程序,例如:
Intent intent = new Intent();
intent.setComponent(new ComponentName("com.example.app1", "com.example.app2.MainActivity"));
intent.putExtra("key", "value");
startActivity(intent);
  1. 从一个服务发送一个自定义类的对象到另一个服务,例如:
IMyAidlInterface myService = IMyAidlInterface.Stub.asInterface(serviceConnection);
Bundle bundle = new Bundle();
bundle.putParcelable("key", myObject);
Intent intent = new Intent();
intent.setComponent(new ComponentName("com.example.app1", "com.example.app2.MyService"));
intent.putExtras(bundle);
sendBroadcast(intent);

Binder

是Android系统中的跨进程通信机制,它可以传递任意类型的对象,包括自定义类的对象。
示例:

  1. 在一个服务中创建一个对象,并将其绑定到另一个服务的Binder接口上,例如:
public class MyService extends Service {
    private final IMyAidlInterface.Stub mBinder = new IMyAidlInterface.Stub() {
        @Override
        public String getMessage() throws RemoteException {
            return "Hello from MyService";
        }
    };

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }
}
  1. 在客户端应用程序中绑定到服务并调用其方法,例如:
IMyAidlInterface myService = IMyAidlInterface.Stub.asInterface(new ServiceConnection() {
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        MyAidlInterface myAidlInterface = IMyAidlInterface.Stub.asInterface(service);
        try {
            String message = myAidlInterface.getMessage();
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }
});
Intent intent = new Intent();
intent.setComponent(new ComponentName("com.example.app1", "com.example.app2"));
bindService(intent, connection, Context.BIND_AUTO_CREATE);

AIDL

是Android系统中的一种接口描述语言,用于定义服务端和客户端之间的接口。
示例同上。

Messenger

是一种轻量级的通信方式,可以在不同的进程之间传递消息。
示例:

  1. 在服务端创建一个Handler对象,并将其封装到一个Binder对象中,例如:
public class MyService extends Service {
    private final IMyAidlInterface.Stub mBinder = new IMyAidlInterface.Stub() {
        @Override
        public String getMessage() throws RemoteException {
            return "Hello from MyService";
        }
    };

    private final Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            Bundle bundle = msg.getData();
            String message = bundle.getString("message");
            Log.d(TAG, "Received message: " + message);
        }
    };

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }
}
  1. 在客户端应用程序中绑定到服务并调用其方法,例如:
IMyAidlInterface myService = IMyAidlInterface.Stub.asInterface(new ServiceConnection() {
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        MyAidlInterface myAidlInterface = IMyAidlInterface.Stub.asInterface(service);
        try {
            Message message = Message.obtain(null, 0, null, myAidlInterface.getMessage());
            myService.mHandler.sendMessage(message);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }
});
Intent intent = new Intent();
intent.setComponent(new ComponentName("com.example.app1", "com.example.app2"));
bindService(intent, connection, Context.BIND_AUTO_CREATE);

ContentProvider

是一种特殊的IContentObserver,用于在不同的应用程序之间共享数据。

以下是一个简单的示例:在主进程中创建一个ContentProvider,然后在子进程中通过ContentResolver访问这个ContentProvider来获取数据。

// 在主进程中注册ContentProvider
public class MyApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        ContentProvider myContentProvider = new MyContentProvider();
        registerContentProvider(myContentProvider);
    }
    
    @Override
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public String getType(Uri uri) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public Uri insert(Uri uri, ContentValues values) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        // TODO Auto-generated method stub
        return 0;
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
        // TODO Auto-generated method stub
        return 0;
    }
}
// 在子进程中通过ContentResolver访问ContentProvider获取数据
public class MyActivity extends Activity {
    private static final String AUTHORITY = "com.example.myapp.provider";
    private static final Uri BASE_CONTENT_URI = Uri.parse("content://" + AUTHORITY);

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Cursor cursor = getContentResolver().query(BASE_CONTENT_URI, null, null, null, null);
        while (cursor.moveToNext()) {
            // TODO: Do something with the data in the cursor.
        }
        cursor.close();
    }
}
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
千里马8年Android系统及应用开发经验,曾担任过美国unokiwi公司移动端技术总监兼架构师,对系统开发,性能优化,应用高级开发有深入的研究,Android开源定制ROM Lineage的贡献者之一,国内首家线下开辟培训Android Framework课程,拥有2年的Android系统培训经验。成为腾讯课堂专业负责android framework课程分享第一人,致力于提高国内android Framework水平Android Framework领域内是国内各大手机终端科技公司需要的人才,应用开发者都对Android系统充满着好奇,其中的binder是重中之重,都说无binder无Android,binde是Android系统的任督二脉。课程水平循序渐进,由中级再到高级,满足各个层次水平的android开发者。1、灵活使用binder进程通信,在app端对它的任何api方法等使用自如2、可以单独分析android系统源码中任何binder部分,分析再也没有难度3、掌握binder驱动本质原理,及对应binder驱动怎么进行进程通信,及内存等拷贝方式数据等4、对binder从上层的java app端一直到最底层的内核binder驱动,都可以顺利理通5、针对系统开发过程中遇到的binder报错等分析方法,及binder bug案例学习6、针对面试官任何的binder问题都可以对答自如7、socket这种进程通信实战使用8、针对android源码中使用的socket源码轻松掌握9、android系统源码中最常见的socketpair中双向进程通信10、使用socket实现一个可以让app执行shell命令的程序

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值