1.Intent
当service在xml中注册时使用到属性android:process时,是不属于当前应用内进程的,此时如果activity启动该service属于进程间通信。
2.AIDL
还是使用service,Binder改成.aidl生成.java文件中的Stub类。该类继承了android.os.Binder类
public class AiDlBinder extends IMyAidlInterface.Stub {
private MyService myService;
public AiDlBinder(MyService myService) {
this.myService = myService;
}
@Override
public void toUpCaseString(String text) throws RemoteException {
myService.toUpCaseString(text);
}
@Override
public void printString(String text) throws RemoteException {
myService.printString(text);
}
}
对应的Service
public class MyService extends Service {
private AiDlBinder myBinder = new AiDlBinder(this);
@Override
public void onCreate() {
super.onCreate();
Log.i("ytt", "MyService onCreate");
/*try {
Thread.sleep(60000);
} catch (InterruptedException e) {
e.printStackTrace();
}*/
}
@Override
public boolean onUnbind(Intent intent) {
Log.i("ytt", "MyService onUnbind");
return super.onUnbind(intent);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i("ytt", "MyService onStartCommand");
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
Log.i("ytt", "MyService onDestroy");
super.onDestroy();
}
@Override
public void onRebind(Intent intent) {
Log.i("ytt", "MyService onRebind");
super.onRebind(intent);
}
@Override
public IBinder onBind(Intent intent) {
Log.i("ytt", "MyService onBind");
return myBinder;
// TODO: Return the communication channel to the service.
// throw new UnsupportedOperationException("Not yet implemented");
}
public void testFun(String text) {
Log.i("yttt", "testFun:" + text);
}
public void toUpCaseString(String text) {
Log.i("ytt", "MyService toUpCaseString"+text);
}
public void printString(String text) {
Log.i("ytt", "MyService printString"+text);
}
}
说到Service有两种启动方式
1.startService--stopService
::使用这种start方式启动的Service的生命周期如下:
onCreate()--->onStartCommand()(onStart()方法已过时) ---> onDestory()
说明:如果服务已经开启,不会重复的执行onCreate(), 而是会调用onStart()和onStartCommand()。
服务停止的时候调用 onDestory()。服务只会被停止一次。
特点:一旦服务开启跟调用者(开启者)就没有任何关系了。
开启者退出了,开启者挂了,服务还在后台长期的运行。
开启者不能调用服务里面的方法。
2.bindService--unbindServie
采用bind的方式开启服务
使用Service的步骤:
1.定义一个类继承Service
2.在Manifest.xml文件中配置该Service
3.使用Context的bindService(Intent, ServiceConnection, int)方法启动该Service
4.不再使用时,调用unbindService(ServiceConnection)方法停止该服务
使用这种start方式启动的Service的生命周期如下:
onCreate() --->onBind()--->onunbind()--->onDestory()
注意:绑定服务不会调用onstart()或者onstartcommand()方法
特点:bind的方式开启服务,绑定服务,调用者挂了,服务也会跟着挂掉。
绑定者可以调用服务里面的方法。
所以activity与service通信我们使用bindService
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
/* private IMyAidlInterface aidlInterface;
private ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
aidlInterface = IMyAidlInterface.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};*/
private Intent intent;
private IMyAidlInterface myBinder;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
intent = new Intent(this, MyService.class);
findViewById(R.id.start).setOnClickListener(this);
findViewById(R.id.stop).setOnClickListener(this);
findViewById(R.id.bind).setOnClickListener(this);
findViewById(R.id.unbind).setOnClickListener(this);
findViewById(R.id.toUpCaseString).setOnClickListener(this);
findViewById(R.id.printString).setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.start:
startService(intent);
break;
case R.id.stop:
stopService(intent);
break;
case R.id.bind:
bindService(intent, serviceConnection, BIND_AUTO_CREATE);
break;
case R.id.unbind:
unbindService(serviceConnection);
break;
case R.id.toUpCaseString:
try {
myBinder.toUpCaseString("啦啦啦,我是toUpCaseString");
} catch (RemoteException e) {
e.printStackTrace();
}
break;
case R.id.printString:
try {
myBinder.toUpCaseString("啦啦啦,我是printString");
} catch (RemoteException e) {
e.printStackTrace();
}
break;
}
}
private ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
myBinder =IMyAidlInterface.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
}
这样实现了一个应用中两个进程间的通信并不是我们需要的,我们想要两个应用之间通信的话应该怎么做呢?
重新新建一个应用,把前一个应用中的.aidl文件拷贝过去,包名必须一样,那新应用中没有MyService,我们就不能使用显示调用,会报找不到该类,所以需要使用隐式调用,现在前一个的demo中给Myservice添加一个action
在客户端隐式调用
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private IMyAidlInterface aidlInterface;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.bind).setOnClickListener(this);
findViewById(R.id.toUpCaseString).setOnClickListener(this);
findViewById(R.id.printString).setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.bind:
Intent intent = new Intent();
intent.setAction("com.gradle.plugin.mydemo.MyAIDLService");
//服务端demo的包名,不是客户端的,android5.0之后必须指定包名
intent.setPackage("com.gradle.plugin.mydemo");
bindService(intent, serviceConnection, BIND_AUTO_CREATE);
break;
case R.id.toUpCaseString:
try {
aidlInterface.toUpCaseString("我是新的哎,MyUserDemo给你的 ");
} catch (RemoteException e) {
e.printStackTrace();
}
break;
case R.id.printString:
try {
aidlInterface.printString("我是新的哎,MyUserDemo给你的 ");
} catch (RemoteException e) {
e.printStackTrace();
}
break;
}
}
private ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
aidlInterface = IMyAidlInterface.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
}
好啦好啦,可以通信啦,可以传递自定义的对象,必须要实现序列化
3.Messenger