Android进程间的通信

由于Android系统中应用程序之间不能共享内存。在不同应用程序之间交互数据(跨进程通讯),Android SDK提供了4种跨进程通讯的方式。这4种方式正好对应Android系统中4种应用程序组件:ActivityContentProviderBroadcastService

**

  1. Activity 可以跨进程调用其它应用程序的Activity
  2. ContentProvider 可以跨进程访问其他应用程序中的数据(以Cursor 对象形式返回),也可以对其他应用程序的数据进行增、删、改操作;
  3. Broadcast 可以向Android系统中所有应用程序发送广播,而需要跨进程通讯应用程序可以监听这些广播;
  4. ServiceContentProvider 类似,也可以访问其他应用程序中的数据,但不同的是,ContentProvider 返回的是Cursor 对象,而Service 返回的是Java 对象,这种可以跨进程的服务叫AIDL服务;**
一、Activity

Activity 的跨进程访问与进程内访问有所不同;虽然他们都需要Intent 对象,但跨进程访问并不需要指定Context 对象和Activity 的Class 对象,而需要指定要访问Activity 所对应的Action(一个字符串)。有些Activity还需要指定一个Uri(通过Intent构造方法的第2个参数指定)。
在Android 系统中很多应用程序提供了可以跨进程访问的Activity,例如,直接调用拨打电话的Activity。

//进程内访
Intent intent = new  Intent(this , Test.class );  
startActivity(intent);
//跨进程访问
Intent callIntent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:13512345678"); 
startActivity(callIntent);
如何将应用程序的Activity共享出去
  1. AndroidManifest.xml文件中指定action
  2. AndroidManifest.xml文件中指定访问协议;指定Uri是需要访问协议,访问协议需要使用<data android:scheme="info" />来指定。如果属性的值是info,那么Uri就应该是“info://Uri的主体部分”,也就是说:访问 协议是Uri的开头部分。
  3. 通过getIntent().getData().getHost()获取到协议后的Uri主体部分;
  4. bundle对象中获得其他应用程序传过来的数据;
  5. 这一步是获得数据后根据需求做处理;

首先创建一个A工程,打开AndroidManifest.xml

 <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
                <!--指定action,自定义动作-->
                <action android:name="net.csdn.MYACTION" />
                <!--指定Uri-->
                <data android:scheme="info" />

                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
public class MainActivity extends AppCompatActivity {
    private EditText edittext;

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


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

        Button button =(Button) findViewById(R.id.button);

        //获取其他应用程序传递过来的数据
        if (getIntent().getData() != null) {
            //获取Host,(info://后面的内容)
            String host = getIntent().getData().getHost();

            Bundle bundle = getIntent().getExtras();
            //其他的应用程序会传递过来一个value值

            String value = bundle.getString("value");
            edittext.setText(host + ":" + value);
        }
    }
}

创建B工程

 button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                Intent intent = new Intent("net.csdn.MYACTION", Uri.parse("info://调用其他应用程序的Activity"));
                intent.putExtra("value","调用成功");
    startActivity(intent);  

            }
        });

这样B程序就可以调用A程序的Activity了

B程序也可以使用startActivityForResult来启动A程序,这样可以得到A程序的返回值。
修改B程序

 button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                Intent intent = new Intent("net.csdn.MYACTION", Uri.parse("info://调用其他应用程序的Activity"));
                intent.putExtra("value","调用成功");
                startActivityForResult(intent,1);
                
            }
        });
  @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {

        Toast.makeText(this, "返回值:" + data.getExtras().getString("result"),
                Toast.LENGTH_LONG).show();

    }

修改A程序

button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {


                Intent intent = new Intent();
                //设置返回的属性值
                intent.putExtra("result",edittext.getText().toString());
                //设置返回码和Intent对象
                setResult(2,intent);
                //关闭Actiivty
                finish();
            }
        });

点击A程序的按钮后,B程序回Toast显示A的返回值。

跨进程访问Activity(访问其他应用程序的Activity)主要是通过一个action来完成的,还需要指定一个Uri。传递数据也可以通过Intent来完成。传递数据的过程是可以双向的。如果想从调用的Activity中返回数据,就需要使用startActivityForResult方法启动Activity

二、ContentProvider

Android 应用程序可以使用文件或SqlLite 数据库来存储数据。ContentProvider提供了一种在多个应用程序之间数据共享的方式(跨进程共享数据)。应用程序利用ContentProvider完成下面的工作

  1. 查询数据
  2. 修改数据
  3. 添加数据
  4. 删除数据

虽然ContentProvider 也可以在同一个应用程序中被访问,但这么做没有意义;ContentProvider 存在的作用是向其他应用程序共享数据和允许其他应用程序对数据进行增、删、改操作。
Android 系统本身提供了很多ContentProvider ,例如:音频、视频、通讯录等;可以通过这些ContentProvider获取相关的信息列表。这些列表数据将以Cursor对象返回;所以,从ContentProvider返回的数据是二维表的形式。
关于ContentProvider的更多内容,请查看我的另一篇文章:Android四大组件之ContentProvider

三、Broadcast

广播是一种被动跨进程通讯的方式。当某个程序向系统发送广播时,其他的应用程序只能被动地接收广播数据。这种象电台进行广播一样,听众只能被动的收听,而不能主动与电台进行沟通。
在应用程序中发送广播比较简单,只需要调用sendBrodcast方法即可;改方法需要一个Intent对象,通过ntent 对象可以发送需要广播的数据。
关于Broadcast的更多内容,请查看我的另一篇文章:Android四大组件之BroadcastReceiver

四、Service

ServiceBroadcast相比而言,虽然实现上稍微麻烦了一点,但它的优势不会像广播那样在手机中的广播较多时会有明显的延时,甚至有广播发送不成功的情况出现。
但是普通的Service 并不能实现跨进程操作,因为普通的Service 和它所在的应用处于同一个进程中,而且它不会专门开一条新的线程,所以如果在普通的Service中实现耗时操作,需要新开线程。
要实现跨进程通信,需要借助AIDL(Android Interface Definition Language)。Android 中的跨进程服务其实采用C/S 的架构,因而AIDL目的是实现通信接口。

客户端每调用一次Content.startService(Intent)Service 就会重新执行一次onStartCommand-->onStart;
但是使用AIDL的话,绑定服务之后,不会重复执行onStart,显然后者的代价更小。
Service:前台Service,像我们经常用的天气、音乐其实利用了前台 Service 来实现。
关于ServiceAIDL的更多内容,请查看我的另一篇文章:Android四大组件之Service

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值