Android实现IPC进程间通信的6种方式 (一)基础篇

1、基本概念
IPC是Inter-Process Communication的缩写,表示进程间通信或跨进程通信。
进程是一个执行单元,一个程序或一个应用,系统会为每个进程分配独立的内存空间。在进程的执行过程中,很有可能需要与别的进程进行通信,比如说我们在淘宝付款时,淘宝就需要调用支付宝,并接收支付宝返回的付款成功与否的消息。因此,我们必须要学会如何进行进程间通信。
2、怎样开启多进程
Android开启多进程的方式很简单,就是在manifest文件中给activity、service等设置process属性,下面我们用实例来说明如何开启多线程。我们定义三个Activity和一个Service,从FirstActivity跳转到SecondActivity,再跳转到ThirdActivity,然后开启MyService

//3个xml文件

?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/button_1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="BUTTON1" />
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/button_2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="BUTTON2"/>
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/button_3"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="BUTTON3"/>
</LinearLayout>

//3个Activity

public class FirstActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_first);
        Button button1=(Button)findViewById(R.id.button_1);
        button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent=new Intent(FirstActivity.this,SecondActivity.class);
                startActivity(intent);
            }
        });
    }
}
public class SecondActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
        Button button2 = (Button)findViewById(R.id.button_2);
        button2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent=new Intent(SecondActivity.this,ThirdActivity.class);
                startActivity(intent);
            }
        });
    }
}
public class ThirdActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_third);
        Button button3 = (Button) findViewById(R.id.button_3);
        button3.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(ThirdActivity.this, MyService.class);
                startService(intent);
            }
        });
    }
}

//MyService

public class MyService extends Service {

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
}

//Manifest文件

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.activitytest">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="ActivityText"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity
            android:name=".FirstActivity"
            android:launchMode="singleTop"
            android:label="This is FirstActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <activity
            android:name=".SecondActivity"
            android:process="com.example.activitytest.activity">
        </activity>

        <activity
            android:name=".ThirdActivity"
            android:process=":activity">
        </activity>

        <service android:name=".MyService"
            android:process="com.example.myservice"/>
    </application>

</manifest>

我们没有给FirstActivity制定process属性,给SecondActivity制定了process属性为“com.example.activitytest.activity”,给ThirdActivity设置的process属性为“activity”,给myService设置的process属性为“com.example.myservice”。
在运行之前我们需要借助Android drvice monitor来查看运行的线程。Android studio工具栏tools --> Android -->android device monitor
在这里插入图片描述
打开之后的界面是这样的,左侧选择我们已经连接好的模拟器或真机,就可以看到已经运行的进程
在这里插入图片描述
接下来我们边操作边查看device monitor的进程
打开程序之后我们会发现多了一个以包名“com.example.activitytest”为进程名的进程,很明显,我们的FirstActivity所在的进程名就是包名,说明进程名默认为包名
在这里插入图片描述
接下来我么点击button1,跳转到SecondActivity,这时增加了我们为SecondActivity指定的进程“com.example.activitytest.activity”
在这里插入图片描述
然后我们再点击button2,跳转到ThirdActivity。这是新增了一个“com.example.activitytest:activity”的进程,说明以:开头的进程,进程名前面会加上包名,实际上,以:开头的进程,是当前进程的私有进程
在这里插入图片描述
然后我们点击button3,开启myService。按照预期出现了我们为MyService指定的进程“com.example.myservice”
在这里插入图片描述
这样我们就开启了4个进程

3、序列化接口
数据要在进程间传输,必须要能够进行序列化和反序列化,Android中有两个序列化接口Serialzable和Parcelable
1)Serialzable是沿用了java中的序列化接口,使用起来非常简单,只需要实现Serializable即可

public class People implements Serializable{

    private String name;

    public People(){}

    public void setName(String name){
        this.name = name;
    }

    public String getName(){
        return name;
    }
}

2)Parcelable使用起来相对比较麻烦

public class People implements Parcelable{

    private String name;

    public People(String name){
    	this.name = name;
    }
    protected People(Parcel in) {
        name = in.readString();
    }

    public static final Creator<People> CREATOR = new Creator<People>() {
        @Override
        public People createFromParcel(Parcel in) {
            return new People(in);
        }

        @Override
        public People[] newArray(int size) {
            return new People[size];
        }
    };

    public void setName(String name){
        this.name = name;
    }

    public String getName(){
        return name;
    }
    
    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(name);
    }
}

3)区别
为什么已经有Serialzable了,Android工程师还要搞出来一个使用起来那么麻烦的Parcelable,肯定是因为Parcelable肯定是有不可替代的优势,那是什么优势呢?
因为Serialzable是Java的序列化接口,使用起来需要大量的I/O操作,开销很大;而Parcelable更适合Android平台,使用起来效率比Serialzable高很多
好了,有了这些基础,我们就可以学习Android进程间通信了
4、进程间通信的方式
Android实现进程间通信的6种方式分别是 Bundle文件共享MessengerAIDLContentProviderSocket
这六种方式我会分别在接下来的六篇博客中手把手带着你实现

下一篇 Bundle实现进程间通信

特别感谢《Android 开发艺术探索》

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值