IPC:进程内部的通信
/**
* started service : 服务同时只会被创建一次,可以通过外部调用stopService 或者自动调用方法来停止
*
* 当执行一个已启的服务,会直接调用onStartCommand方法来执行业务
*
*/
public class MyService extends Service {
public MyService() {
}
@Override
public void onCreate() {
super.onCreate();
Log.i("msg","my service create");
}
//在该方法中实现核心业务
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
for (int i=0;i<50;i++){
Log.i("print","onstartcommand"+i);
this.stopSelf();//自动停止
}
return super.onStartCommand(intent, flags, startId);
}
@Override
public IBinder onBind(Intent intent) {
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public void onDestroy() {
super.onDestroy();
Log.i("destroy","销毁服务");
}
}
配置清单注册服务:
<!--注册service
加 android:process=":removte" :给进程起个名字,会在单独的进程中运行
-->
<service
android:name=".MyService"
android:enabled="true"
android:exported="true" >
</service>
/**
*
*
* IntentService
* 1.内部有一个工作线程来完成耗时的操作。只需要实现onHandleIntent 方法即可
*
* 2.完成工作后会自动停止服务
*
* 3.如果同时执行多个任务时,会以工用对列的方式依次执行。
*
* 4.通过使用该类完成本APP中的内部耗时工作
*
*
*/
public class MyIntentService extends IntentService {
public MyIntentService(){
super("myIntentService");
}
@Override
protected void onHandleIntent(Intent intent) {
for (int i=0;i<50;i++){
Log.i("MSG","打印for"+i);
}
}
}
清单配置文件:
<service
android:name=".MyIntentService"
android:exported="false" >
</service>
这里是异步绑定的,当绑定上了,再通知,并不是立即绑定的
AIDL :安卓接口定义语言
创建aidl文件:
// ICat.aidl
package com.example.zhangjb.servicecom; //用于给queryLocalInterface方法使用业得到实现业务对象
interface ICat {
//定义方法
void setName(String name);
String desc();
void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
double aDouble, String aString);
}
--------------------------------------------------
实现aidl类:
/**
* Created by zhangjb on 2015/10/10.
*
* 业务接口的具体实现类
*/
public class CatImpl extends ICat.Stub{
private String name;
@Override
public void setName(String name) throws RemoteException {
this.name = name;
}
@Override
public String desc() throws RemoteException {
return name;
}
@Override
public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {
}
}
---------------------------------------------------
/****
* 绑定服务:
* 1.客户端通过bindService方法来绑定一个服务对象,如果绑定成功,会回调用ServiceConnection 接口方法 onServiceConnected
*
* 2.通过Service 组件来暴露 业务接口,
*
* 3.业务接口应该符合 onBind的规则
*
* 4.服务端通过一个*.aidl 文 件业定义一个可以被客户端调用的业务接口
*
* 5.一个aidl文件:
* 1.不能有修饰符,类似接口的写法
* 2.支持类型有:8种基本数据类型, String ,CharSequence ,List<String>,MAP,自定义类型
*
* 4.服务端需要提供一个业务接口的实现类,通过我们会 extends Stub类
*
* 5.通过Service 的onBind 方法返回被绑定的业务对象
*
* 6.客启端如果绑定成功,就可以像调用自己的方法一样调用远程的业务对象方法
*
* 自定定类型 :
* 1.实现Parcelable接口
* 2.定义一个aidl文件声明该类型
3.在其它adild文件中导入
started启动的服务,会长期存在,只要不停,
bind启动的服务,通常会在解绑时停止
技巧:
先started,后bind
*
*
*/
//bind service 服务类
public class MyBService extends Service {
public MyBService() {
}
@Override
public void onCreate() {
super.onCreate();
}
@Override
public IBinder onBind(Intent intent) {
return new CatImpl();//具体实现的业务类
}
@Override
public boolean onUnbind(Intent intent) {
return super.onUnbind(intent);
}
@Override
public void onDestroy() {
super.onDestroy();
}
}
-----------------------------------------------
public class MainActivity extends ActionBarActivity {
private ICat cat;
private boolean mbound = false;//是否绑定
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
====================================================================
//启动service服务 :开启后会一直在后台运行
public void startClick(View v){
Intent intent = new Intent(this,MyService.class);
startService(intent);
}
//停止service服务
public void stopClick(View v){
Intent intent = new Intent(this,MyService.class);
stopService(intent);
}
//启动 intenService服务:只执行一次,并自动结束
public void startIntenClick(View v){
Intent intent = new Intent(this,MyIntentService.class);
startService(intent);
}
===============bind Service 实现,通过IPC调用业务方法===============================
//绑定服务的连接回调接口
private ServiceConnection conn = new ServiceConnection() {
//绑定成功后回调的方法
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
//这里的IBinder:就是 aidl 的具体实现业务类
cat = ICat.Stub.asInterface(service);//返回的是CatImpl的对象(业务实现对象),
//说明在同一下进程当中
//在清单文件中配置 android:process=":removte" 时,则返回Icat的代理对象,因为正在MyBService服务类已经在一个独立的进程中运行这个服务,需要网络传输,所以需要代理。当ipc调用时,就会将传入的值,传到另一个进程中去了,这样就形成了远程的调用服务,调用的是单独的一个进程中的服务
mbound = true;
Toast.makeText(MainActivity.this,"绑定成功",Toast.LENGTH_SHORT).show();
}
//服务异常中止,会自动调用这个方法
@Override
public void onServiceDisconnected(ComponentName name) {
mbound = false;
}
};
//当前客户端绑定一个服务
public void BoundClick(View v){
Intent intent = new Intent(this,MyBService.class);
//异步绑定
bindService(intent,conn, Context.BIND_AUTO_CREATE);//没有绑定自动创建
}
//客户端解除一个服务
public void unBoundClick(View v){
if(mbound){
unbindService(conn);
Toast.makeText(MainActivity.this,"解除绑定成功",Toast.LENGTH_SHORT).show();
}
}
//只有当服务绑定的时候才能调用
public void callClick(View view){
if(cat==null){
return;
}
try {
cat.setName("猫猫");
Toast.makeText(this,cat.desc(),Toast.LENGTH_SHORT).show();
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
**通过IPC调用业务方法,是通过服务类来绑定的,service为一个中间人**
ipc自定义类型
1.aidl文件:
// IPCCat.aidl
package com.example.w7.myapplicationipc;
//导入 Person
import com.example.w7.myapplicationipc.Person;
// Declare any non-default types here with import statements
interface IPCCat {
Person getPerson();
void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
double aDouble, String aString);
}
//创建person类:
/**
* Created by w7 on 2015/10/11.
*/
public class Person implements Parcelable{
String name;
String work;
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", work='" + work + '\'' +
'}';
}
public static final Parcelable.Creator<Person> CREATOR = new Parcelable.Creator<Person>() {
@Override
public Person createFromParcel(Parcel source) {
Person p =new Person();
p.name = source.readString();
p.work = source.readString();
return p;
}
@Override
public Person[] newArray(int size) {
return new Person[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeString(work);
}
}
2.adil声明:
// Person.aidl
package com.example.w7.myapplicationipc;
//使用Parcelable声明这个类
parcelable Person;
3.业务类:
/**
* Created by w7 on 2015/10/11.
*/
public class IPcImple extends IPCCat.Stub {
@Override
public Person getPerson() throws RemoteException {
Person p = new Person();
p.name = "猫猫的主人";
p.work = "强盗";
return p;
}
@Override
public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {
}
}
4.服务类:
public class MyBindS extends Service {
public MyBindS() {
}
@Override
public void onCreate() {
super.onCreate();
}
@Override
public void onDestroy() {
super.onDestroy();
}
@Override
public IBinder onBind(Intent intent) {
return new IPcImple();
}
@Override
public boolean onUnbind(Intent intent) {
return super.onUnbind(intent);
}
}
5.activity客户端:
public class MainActivity extends Activity {
private IPCCat cat;
private boolean mbound = false;//是否绑定
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
private ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
cat = IPCCat.Stub.asInterface(service);//使用接口类来接收实现类对象
mbound = true;
Toast.makeText(MainActivity.this, "绑定成功", Toast.LENGTH_SHORT).show();
}
@Override
public void onServiceDisconnected(ComponentName name) {
mbound = false;
}
};
//ipc谳用业务方法
public void getInfo(View v) {
if (cat == null) {
return;
}
try {
Toast.makeText(this, cat.getPerson().toString(), Toast.LENGTH_SHORT).show();
} catch (RemoteException e) {
e.printStackTrace();
}
}
// 绑定服务
public void clickIPC(View v) {
Intent intent = new Intent(this, MyBindS.class);
bindService(intent, conn, Context.BIND_AUTO_CREATE);
}
//解除绑定
public void clickUnbind(View v) {
if (mbound) {
unbindService(conn);
Toast.makeText(MainActivity.this, "解除绑定成功", Toast.LENGTH_SHORT).show();
}
}
}
public class MassengerService extends Service {
public static final int say_hello = 0x1;//消息的标记
public MassengerService() {
}
@Override
public IBinder onBind(Intent intent) {
return messenger.getBinder();
}
//服务端接收并处理信息
private Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
switch (msg.what){
case say_hello://当为这个标记时,处理这个信息
String info = (String) msg.obj;
Toast.makeText(getApplicationContext(),info,Toast.LENGTH_SHORT).show();
break;
}
}
};
private Messenger messenger = new Messenger(handler);
}
-------------------------------------------------------------
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
Messenger mService;
boolean flag = false;
private ServiceConnection conn2 = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mService = new Messenger(service);
flag = true;
}
@Override
public void onServiceDisconnected(ComponentName name) {
flag = false;
}
};
//一启动的时侯就绑定服务
@Override
protected void onStart() {
super.onStart();
Intent service = new Intent(this, MassengerService.class);
bindService(service, conn2, Context.BIND_AUTO_CREATE);
}
@Override
protected void onStop() {
super.onStop();
if (flag) {
unbindService(conn2);
flag = false;
}
}
//单击按钮发送信息
public void messageClick(View v) {
//获取(创建) 一个消息对象
Message msg = Message.obtain();
msg.what = MassengerService.say_hello;
msg.obj = "这是一个message信息!";
try {
mService.send(msg);//发送消息
} catch (RemoteException e) {
e.printStackTrace();
}
}
}