Android进程间通信方式总结(IPC)

时间:2022-05-01 16:15:22

第一种:Intent方式

Intent分为两种,一种是显式Intent,只适合在同一进程内的不同组件之间通信,例如 new Intent(this,Target.class).

另外一种是隐式Intent,在AndroidMainifest.xml中注册,一般可以用户跨进程通信,例如new Intent(String action).

下面就介绍隐式Intent跨进程通信的例子:

Project A 中的代码比较简单,主要就是在的button onClick事件中:

button.setOnClickListener(new OnClickListener()
        {           
            @Override public void onClick(View v)
            {     
                Intent intent = new Intent();
                intent.setAction("com.example.IPCByIntent");
                intent.putExtra("data", "this is ipc by intent");
                startActivity(intent);
             
            }
        });

其中intent.SetAction里面的值是Project B中定义的。


在Project B中的AndroidMainifest.xml,在MainActivity的第二个intent-filter中,添加在Project A中用到的action值

      <activity
android:name="com.example.adildemo.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="com.example.IPCByIntent"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>

在Project B的MainActivity.java的OnCreate方法中,添加如下代码

       Intent intent = this.getIntent();
if(null != intent.getStringExtra("data")){
tv.setText(intent.getStringExtra("data"));
}


先运行Project B,在运行Project A,点击 Porject A 的button,则Project B上的textview 将会显示 this is ipc by intent.

Intent 可以非常方便的通信,但是它是非实时的,无法进行实时的像函数调用那样的实时通信。


第二种方式:AIDL方式

AIDL方式应该是应用的比较多的一种方式,下面介绍一个简单的例子来实现用AIDL解决进程之间的数据传递。

有两个Project,AIDLDemo 和AIDLDemoClient,AIDLDemo里面有一个Service,我们当作是Server Project,另外一个AIDLDemoClient我们当作是Client.


首先看Server Project,首先新建一个File,myAidl.aidl,注意后缀名要是.aidl.其实就是一个接口文件,在该文件中:

1.我们不需要使用public,protected,private等修饰符.

2.对于基本类型,如int,String等我们不需要import.

3.如果在文件中引用别的aidl文件接口,需要import进来,即使在一个包下面也需要import.

package com.sha.aidl;

interface myAidl{
int add(int x,int y);
String get();
}


定义好myAidl.aidl文件以后,build project,系统会给我们自动生成一个myAidl.java文件,在gen下面


然后在AndroidMainifest.xml中注册静态Service如下:

        <service android:name="com.example.adildemo.myService">
<intent-filter >
<action android:name="com.example.adildemo.myService"/>
</intent-filter>

</service>


定义Service文件

这里面核心的步骤就是定义了一个 myAidl.Stub的 Binder,然后在onBinder函数里面,返回这个Binder.

package com.example.adildemo;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;

import com.sha.aidl.myAidl;

public class myService extends Service
{
@Override public IBinder onBind(Intent intent)
{
return myBinder;
}

private myAidl.Stub myBinder = new myAidl.Stub()
{

@Override public int add(int x, int y) throws RemoteException
{
return x + y;
}

@Override public String get() throws RemoteException
{
return "test";
}

};
}

至此,Server Project的工作就完成了。


下面看看Client Project的内容:

把ADILDemo里面的myAidl.aidl拷贝到ADILDemo_Client项目中,注意myAidl.aidl的包名一定要一致,如果不一致会出现错误。


Android进程间通信方式总结(IPC) Android进程间通信方式总结(IPC)


在ADIDemo_Client的MainActivity.java文件中:


首先在OnCreate函数里面,绑定Service,定义一个ServiceConnection变量,通过调用myAidl.stub.asInterface(IBinder)方法获取myAidl变量,然后调用myAidl变量的get方法

package com.example.adildemo;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.example.adildem.R;
import com.sha.aidl.myAidl;

public class MainActivity extends Activity
{
private Button button;
private myAidl aidl;
private TextView tv;

private ServiceConnection sc = new ServiceConnection()
{

@Override public void onServiceDisconnected(ComponentName name)
{
aidl = null;

}

@Override public void onServiceConnected(ComponentName name, IBinder service)
{
aidl = myAidl.Stub.asInterface(service);

}
};

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

button = (Button)findViewById(android.R.id.button1);
tv = (TextView)findViewById(android.R.id.text1);

Intent intent = new Intent("com.example.adildemo.myService");
bindService(intent, sc, Context.BIND_AUTO_CREATE);

/* Intent intent = this.getIntent();
if(null != intent.getStringExtra("data")){
tv.setText(intent.getStringExtra("data"));
}*/

button.setOnClickListener(new OnClickListener()
{

@Override public void onClick(View v)
{

String result = "";
try
{
result = aidl.get();
}
catch (RemoteException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
Toast.makeText(MainActivity.this, result+"", Toast.LENGTH_SHORT).show();
}
});

}

}

先运行AIDLDemo project,再运行AIDLDemoClient project,点击button,弹出toast,表示client调用server成功

第三种方式:Messenger方式

AndroidMainifest.xml中注册静态Service如下:

        <service android:name="com.example.aidldemomessager.myService">
<intent-filter>
<action android:name="com.example.aidldemomessager.myService"/>
</intent-filter>
</service>


Service文件:

package com.example.aidldemomessager;

import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.widget.Toast;

public class myService extends Service
{

private Handler serviceHandler = new Handler(){

@Override public void handleMessage(Message msg)
{
Toast.makeText(getApplicationContext(), "test", Toast.LENGTH_LONG).show();
}

};

private Messenger messager = new Messenger(serviceHandler);

@Override public IBinder onBind(Intent intent)
{
return messager.getBinder();
}

}

MainActivity文件

package com.example.aidldemomessager;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;


public class MainActivity extends Activity
{


private Button button;

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

Intent intent = new Intent("com.example.aidldemomessager.myService");
bindService(intent, sc, Context.BIND_AUTO_CREATE);

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

button.setOnClickListener(new OnClickListener()
{

@Override public void onClick(View v)
{

Message msg = new Message();
msg.what = 1;
try
{
messenger.send(msg);
}
catch (RemoteException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}


private Messenger messenger;

private ServiceConnection sc = new ServiceConnection()
{

@Override public void onServiceDisconnected(ComponentName name)
{
messenger = null;
}

@Override public void onServiceConnected(ComponentName name, IBinder service)
{
messenger = new Messenger(service);
}
};




}