一、什么是Service?
Service是Android系统中的四大组件之一,它是一种长生命周期的,没有可视化界面,运行于后台的一种服务程序。Service运行在主线程中,可以跨线程调用。它的优先级比较高,它比处于前台的应用优先级低,但是比后台的其他应用优先级高,这就决定了当系统因为缺少内存而销毁某些没被利用的资源时,它被销毁的概率很小。
二、Service启动有两种方式,startService和bindService:
Android之startService()和bindService()区别
- 生命周期:
startService()方式启动,Service是通过接受Intent并且会经历onCreate()和onStart()。当用户在发出意图使之销毁时会经历onDestroy(),而bindService()方式启动,与Activity绑定的时候,会经历onCreate()和onBind(),而当Activity被销毁的时候,Service会先调用onUnbind()然后是onDestroy()。
- 控制方式:
前者的控制方式需要使用固定的方法,对Service进行单一的操作。而后者由于与Activity绑定,不用考虑其生命周期问题,并且从发送Intent的被动操作,变为可以主动对Service对象进行操作,我们甚至可以建立一个Handler类,对Service进行相关的操作。大大加强了Service的灵活性、可操作性。
总结:对于简单的应用startService()启动方式能带来更少的代码,简单的操作。对于复杂的应用bindService()方式,虽然带来的更多的编码,但同时也带来了更好的可操作性,使其使用起来更像Activity。
三、startService的使用:
startService优点:
使用简单,和Activity一样,只需要几行代码就能启动;
startService缺点:无法直接获得Service对象,不能直接操作Service中的属性和方法,只能通过Intent传递不同的参数,重复调用StartService;
新建类继承Service
public class MusicService extends Service
1.重写onCreate方法
Service在创建时调用的方法,可以用来做数据初始化,Service在没有停止之前,只会执行一次。
2.实现onBind方法
由于Service是一个抽象类,定义了一个onBind抽象方法,所以必须实现此抽象方法,return null 即可,此方法在startService方式用不上,无需理会。
3.重写onStartCommand方法
Service创建后会调用onStartCommand,此方法中可以接收调用者传递过来的参数,并且可以编写需要的逻辑代码,当重复调用Service时,onStartCommand会重复执行,onStart方法已弃用。
4.重写onDestroy方法
Service在退出时调用,此方法中可以编写释放资源的操作。
5.在AndroidManifest文件中注册Service
<service
android:name=".MyService"
android:enabled="true"
android:exported="true"></service>
6.使用startService方法启动Service
Intent intent1=new Intent(this,MyService.class);
startService(intent1);
7.使用stopService方法停止Service
Intent intent2=new Intent(this,MyService.class);
stopService(intent2);
注意:
onCreate只会在创建时执行一次,但只要调用startService方法,onStartCommand一定会执行
调用stopService后,Service会执行onDestroy方法后停止。
无法获得Service对象,不能直接操作Service中的属性和方法。
四、使用Service实例:将Service执行结果打印出来:
首先创建一个Activity,布置其xml代码:
用两个按钮Button开启、停止Service
<Button
android:id="@+id/start_service"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="StartService" />
<Button
android:id="@+id/stop_service"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="StopService" />
布置Java代码:
绑定ID、添加监听、添加点击事件
public class Main1Activity extends AppCompatActivity implements View.OnClickListener {
private Button startBtn;
private Button stopBtn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main1);
bindId();
}
private void bindId() {
startBtn=findViewById(R.id.start_service);
stopBtn=findViewById(R.id.stop_service);
stopBtn.setOnClickListener(this);
startBtn.setOnClickListener(this);
}
@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.start_service:
Intent intent1=new Intent(this,MyService.class);
startService(intent1);//开启服务
break;
case R.id.stop_service:
Intent intent2=new Intent(this,MyService.class);
stopService(intent2);//停止服务
break;
default:
break;
}
}
}
创建一个MyService类继承Service
代码如下:
在onStartCommand方法里写一个子线程,看Service的工作顺序
public class MyService extends Service {
public MyService() {
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
return mBinder;
}
//服务第一次创建时调用
@Override
public void onCreate() {
super.onCreate();
Log.e( "onCreate: ", "创建Service");
}
//每一次启动服务都会调用
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e( "onStartCommand: ", "启动Service");
new Thread(new Runnable() {
@Override
public void run() {
for (int i=0;i<=10;i++)
{
Log.e( "Service"+Thread.currentThread().getName(),i+"-------");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
Log.e( "onDestroy: ", "停止Service");
}
}
四、bindService的使用及优缺点:
bindService的优缺点:
优点:可以得到Service对象,灵活控制Service内部的属性方法;
缺点:使用复杂;
使用bindService绑定Service的步骤:
1.新建类继承Service
实现onBind方法
这里不同于startService中实现onBind方法那样简单。这里需要在此方法中返回一个Binder子类对象。
2. 重写onCreate方法
3.重写onUnBind方法
在调用unbindService方法解除绑定后,触发此回调函数
4.重写onDestroy方法
5.在AndroidManifest中注册Service
实现ServiceConnection接口
这里是难点,通过代码示范。
通过bindService绑定Service
通过unbindService解绑Service
bindService使用实例
<Button
android:id="@+id/bind_btn"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="bindservice" />
<Button
android:id="@+id/unbind_btn"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="unbindservice" />
public class Main2Activity extends AppCompatActivity implements View.OnClickListener{
private Button bindBtn;
private Button unBindBtn;
private MyService.DownloadBinder downloadBinder;
private ServiceConnection connection=new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
downloadBinder=(MyService.DownloadBinder)iBinder;
downloadBinder.startDownload();
downloadBinder.getProgress();
Log.e( "onServiceConnected: ", "+++++++++++++++++");
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
Log.e( "onServiceDisconnected: ", "11111111111111111");
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
bindId();
}
private void bindId() {
bindBtn=findViewById(R.id.bind_btn);
unBindBtn=findViewById(R.id.unbind_btn);
}
@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.bind_btn:
Intent intent=new Intent(Main2Activity.this,MyService.class);
bindService(intent,connection,BIND_AUTO_CREATE);
break;
case R.id.unbind_btn:
Intent intent1=new Intent(this,MyService.class);
unbindService(connection);
break;
}
}
}