什么是Service
Service见名知意“服务”,略懂windows基础的童鞋都会听说过服务吧。比如控制机器连接网络,是否可以发射WIFI信号等都是由服务控制的,android的中服务有一些略微的区别,主要用做于后台,虽然程序已经退出,但依然可以播放歌曲,下载视频…….。Service类似于Activity,所以也需要启动,只是无界面,不可交互,可以长时间运行在后台(不要进行耗时操作),是APP的组件。
什么要使用Service
可能会有人有疑问,我新开一个工作线程,程序退出了依然可以执行播放歌曲,下载视频,为什么要用Service,以下是在网上搜索的相关资料:
(1)、Service可以放在独立的进程中,所以更安全;
(2)、使用Service可以依赖现有的binder机制,不需要在应用层面上处理线程同步的繁杂工作;
(3)、系统可以重新启动异常死去的Service。
如何使用Service
1.两种启动方式:
(1) Context中的startService()
这种启动方式即使启动的控件即使调用者退出也不会结束Service
(2) Context中bindService();
调用者和Service绑定在一起,调用者退出,服务也就终止。该种启动方式用于传值使用。
做为四大组件,记得要配置<service>节点:
<service android:name="com.example.bandingservice.Service2305"></service>
2.Service生命周期:
根据上图不难看出分两种启动方式,并且生命周期方法不同。
startService启动:
生命周期三个方法:onCreate-->onStartCommand-->onDestroy
三个方法详细说明:
1) onCreate第一次创建Service实例会调用
2)onStartCommand()可以多次被执行 (2.0之前onStart);
3)onDestroy销毁Service
当startService的时候会依次调用onCreate()à onStartCommand(),此时服务已经正常启动了。
如果调用者退出了,而调用者启动的Service未退出,则该服务一直启动,Service事情一旦做完,应该停止它,stopSelf()、stopService()。
bindService启动:
生命周期方法:onCreate-->onBind-->onUnbind-->onDestroy
1)onCreate:同上
2)onBind:onCreate一样,一个实例只会调用一次
3)onUnbind解除绑定,注意:在解除绑定之前需要判断调用者是否已经绑定,否则会抛java.lang.IllegalStateException: Could not execute method of the activity
bindService(service, conn, flags)参数详解:
参数1:Intent的要启动的Service
参数2:ServiceConnection的实例,用于监听Service连接的情况,连接成功回调ServiceConnection对象的onServiceConnected(ConpontName name,IBinder service)方法,异常终止调用ServiceConnection的onServiceDisconnected(ConponentNamename)方法。该参数同时是调用者和service之间的通讯
参数3:指定是自动创建Service(如果Service还未创建),可以指定0,或者BIND_AUTO_CREATE(自动创建)
以下是代码:
MainActivity:
package com.example.bandingservice; import com.example.bandingservice.Service2305.MyBinder; import android.app.Activity; import android.app.Service; 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.view.View; import android.widget.Toast; public class MainActivity extends Activity { MyServiceConnection conn; //标示位 private boolean isConn = false; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); conn = new MyServiceConnection(); } public void btn(View view) { switch (view.getId()) { case R.id.btn1:// 绑定Service Intent intent = new Intent(this, Service2305.class); //三个参数上面已经注明 bindService(intent, conn, Context.BIND_AUTO_CREATE); break; case R.id.btn2:// 解绑Service if (isConn) { unbindService(conn); } break; default: break; } } class MyServiceConnection implements ServiceConnection { //访问者与Service连接情况,连接成功调用该方法 参数2是Service2305的public IBinder onBind返回值 @Override public void onServiceConnected(ComponentName name, IBinder service) { MyBinder mBinder = (MyBinder) service; // 获取Service实例 Service2305 mService = mBinder.getService(); String servieceStr = mService.getServieceStr(); Toast.makeText(MainActivity.this, servieceStr, 0).show(); } // Service意外断开连接调用 @Override public void onServiceDisconnected(ComponentName name) { isConn = false; } } }
Service2305.java
package com.example.bandingservice; import android.app.Service; import android.content.Intent; import android.os.Binder; import android.os.IBinder; import android.util.Log; public class Service2305 extends Service { private final String TAG = "Service"; private MyBinder binder = new MyBinder(); //绑定时会调用 返回值不要空 返回到客户端的onServiceConnected @Override public IBinder onBind(Intent intent) { return binder; } @Override public void onCreate() { super.onCreate(); } @Override public boolean onUnbind(Intent intent) { return super.onUnbind(intent); } @Override public void onDestroy() { super.onDestroy(); } // Binder是IBinder的子类 class MyBinder extends Binder { //返回当前Service的实例 public Service2305 getService() { return Service2305.this; } } // 体验:客户端调用服务端的方法 public String getServieceStr() { return "service的数据"; } }
startService和bindService结合启动:
为了Activity和Service交互需要绑定,并且解绑之后又不希望停止Service就会使用两种方式结合启动。
//启动Service
startService(new Intent(MainActivity.this,Service2306.class));
//要交互的数据 ServiceConnection中的onServiceConnected
bindService(new Intent(MainActivity.this,Service2306.class), conn, Context.BIND_AUTO_CREATE);
unbindService(conn);//解绑Service API建议写在activity中的onDestroy()方法里
3.跨进程(APP)组件与APP交互:(相当于客户端和服务器)
大家都知道线程之间的交互可以使用Handler,进程之间的交互也同样需要一个类,这就是Messenger(信使),Messenger 主要作用是将调用者和后台Service进行交互,在服务器构建Messenger 的实例需要Handle的对象作为构造参数,在通过调用Messenger的getBinder()给客户端返回IBind实例,废话不说上代码
Service类:
public class Service2402 extends Service{
//接收客户端请求---》处理请求
class MyHandler extends Handler{
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
System.out.println("处理客户端的请求:"+msg.what);
}
}
//信使
final Messenger messenger=new Messenger(new MyHandler());
@Override
public IBinder onBind(Intent intent) {
//信使分享一个IBinder给客户端
return messenger.getBinder();
}
}
MainActivity类:
public class MainActivity extends Activity {
private Messenger messenger;
private Conn conn;
private boolean isConn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
conn=new Conn();
//绑定上Service
bindService(new Intent(MainActivity.this,Service2402.class), conn, Context.BIND_AUTO_CREATE);
//按钮点击--》给Service发送指令
findViewById(R.id.btn).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Message msg=Message.obtain();
msg.what=1;
try {
messenger.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}
}
});
}
class Conn implements ServiceConnection{
//连接上服务
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
//Messenger对象---->给Service发指令
messenger=new Messenger(service);
isConn=true;
}
//意外断开连接
@Override
public void onServiceDisconnected(ComponentName name) {
messenger=null;
isConn=false;
}
}
@Override
protected void onDestroy() {
if(isConn){
unbindService(conn);
}
super.onDestroy();
}
通过代码分析,客户端创建Messenger 将IBinder service做为参数才生成的Messenger 的实例,发送的时候同样使用Messenger 的实例,而不是Handle。