1.Service的简单创建
A. 创建一个MyService 继承Service 实现OnBind()方法
B. 在AndroidManifest文件中,<application></application>节点之间,配置自定义的服务<service></service>
C. 在activity中,通过显式调用服务:
Intent intent = new Intent(this, MyService.class);
startService(intent);
D. 在activity中,通过stopService(intent);来结束该服务
注意:在启动服务【Context.startService(intent)】时,不要忘记也要相应的关闭服务【Context.stopService(intent)】
2.Service的绑定与解绑
A. 在Activity中,使用bindService(intent, conn, BIND_AUTO_CREATE);
绑定该Activity.
private MyConnection conn = new MyConnection();
private class MyConnection implements ServiceConnection
{
/**服务连接成功调用该方法*/
@Override
public void onServiceConnected(ComponentName name, IBinder service)
{
Log.i("AAA","onServiceConnected");
}
/**服务断开连接调用该方法*/
@Override
public void onServiceDisconnected(ComponentName name)
{
Log.i("AAA","onServiceDisconnected");
}
}
B. 在Activity中,使用unbindService(conn);解绑。
注意:
#startService
* 该方法启动服务所在的进程属于服务进程
* Activity一旦启动服务,服务就与Activity一毛钱关系也没有了
#bindService
* 该方法启动的服务所在进程不属于服务进程
* Activity与服务建立了连接,Activity一旦死亡,服务也跟着死亡
3.Service与Activity通信
方法1:
A. 在自定义的Service的OnBind方法中,返回一个自定义的Binder,在该Binder类中,实现与Activity的通讯
public class MyService extends Service
{
@Nullable
@Override
public IBinder onBind(Intent intent)
{
Log.i("AAA","onBind");
return new MyBinder();
}
// 自定义一个Binder 处理自己需要处理的事件
public class MyBinder extends Binder
{
public void show()
{
showToast();
}
}
}
B. 在2 MyConnection 类onServiceConnected方法中
private MyService.MyBinder myBinder;
/**服务连接成功调用该方法*/
@Override
public void onServiceConnected(ComponentName name, IBinder service)
{
Log.i("AAA","onServiceConnected");
myBinder = (MyService.MyBinder)service;
}
在需要调用的地方直接通过myBinder.xxx()调用方法,注意需要对myBinder判空
方法2:
A. Binder实现自定义接口的方式
public class MyService extends Service
{
@Nullable
@Override
public IBinder onBind(Intent intent)
{
Log.i("AAA","onBind");
return new MyBinder();
}
// 自定义一个Binder 处理自己需要处理的事件
public class MyBinder extends Binder implements MyServiceImpl
{
// 实现接口的方式
@Override
public void showToast()
{
// TODO
}
@Override
public void Log()
{
// TODO
}
}
}
/**
* Created by Administrator on 2016/6/12.
*/
public interface MyServiceImpl
{
void showToast();
void Log();
}
B. 与上一基本类似
在2 MyConnection 类onServiceConnected方法中
private MyServiceImpl myServiceImpl;
/**服务连接成功调用该方法*/
@Override
public void onServiceConnected(ComponentName name, IBinder service)
{
Log.i("AAA","onServiceConnected");
myServiceImpl= (MyServiceImpl )service;
}
在需要调用的地方直接通过myServiceImpl.xxx()调用方法,注意需要对myBinder判空
注意:
* Serviec与Activity通讯,通过一个中间人(Binder)来进行通讯。
4.服务的分类及远程服务的使用
* 本地服务:指的是服务和启动服务的Activity在同一个进程中。(即在同一个app应用中)
* 远程服务:指的是服务和启动服务的Activity不在同一个进程中。
A. Android 调用远程服务:
# App 1
* 新建一个服务,并且在AndroidManifest文件的 <application></application>节点中,定义该服务
<service android:name=".service.RemoteService">
<intent-filter>
<action android:name="com.mbcb.myapptwo.remote" />
</intent-filter>
</service>
# App 2
# 启动服务是调用以下代码:
Intent intent = new Intent();
intent.setAction("com.mbcb.myapptwo.remote"); // app 1注册的Action
intent.setPackage("com.mbcb.myapptwo"); // app1 的包名
startService(intent);
# 注意:
在android 5.0以后,必须调用intent.setPackage方法,否者会出现闪退的异常(Service Intent must be explicit)
5. 服务AIDL(Android Studio)
A. 创建一个简单的Service,并在AndroidManifest文件中,配置该Service(步骤如4)
B. App 2中调用App 1 Service的方法,需要通过使用AIDL文件来调用。
C. 在含Service的App中,步骤如下:
* 在main文件夹中右键 --> new --> AIDL文件
* 定义好了AIDL文件后,检查main/aidl文件夹下的包名是否与AndroidMainfest中的包名一致。
* 此时,aidl文件虽然已经生成了,但是并没有生成java文件(build/genrated/source/aidl/debug)
* 在工具栏Build下,点击Make Project(ctrl+f9)之后,会aidl文件会生成java文件
* 在service中,自定义binder:
// 自定义binder,并在onBind方法中创建该类
private class MyBinder extends RemoteInterface.Stub
{
@Override
public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
double aDouble, String aString) throws RemoteException
{
}
@Override
public void say() throws RemoteException
{
Log.i("AAA", "Hello world");
}
}
@Nullable
@Override
public IBinder onBind(Intent intent)
{
Log.i("AAA", "onBind");
return new MyBinder();
}
D. 在需要调用App 1服务的App中,如App 2。
* 把App 1中的main下的aidl文件夹直接拷贝到App 2的main文件夹下。
* 通过以下代码远程调用服务
MyConnection conn = new MyConnection();
Intent intent = new Intent();
intent.setAction("com.mbcb.myapptwo.remote"); // app 1注册的Action
intent.setPackage("com.mbcb.myapptwo"); // app1 的包名
bindService(intent, conn, BIND_AUTO_CREATE);
# 注意:
在android 5.0以后,必须调用intent.setPackage方法,否者会出现闪退的异常(Service Intent must be explicit)
private RemoteInterface remoteInterface;
private class MyConnection implements ServiceConnection
{
@Override
public void onServiceConnected(ComponentName name, IBinder service)
{
remoteInterface = RemoteInterface.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name)
{
}
}
* 调用App 1服务的方法:(ctrl + alt + T 生成try/catch的快捷键)
try
{
remoteInterface.say();
} catch (RemoteException e)
{
e.printStackTrace();
}