Android中Service学习笔记
Service的基本使用方法
Service的启动方式有两种,第一种是使用startService()和stopService()方法来启动和停止Service;第二种是使用bindService()方法来绑定Service(此方法可以随时获取Service的执行状态和参数)。
1. 注意要点:
- startService()之后,onCreate()只执行一次,在Service没有被创建时候,执行创建。此后再运行startService()方法,都只执行onStartCommand()方法。当执行stopService()或者在Service中任何地方调用自身的stopSelf()方法后,服务将停止。此后再次调用stopService()方法,将不再起作用,也不报错。执行过程:startService()——>onCreate()——>onStartCommand()——>stopService()——>onDestory();其中startService()和stopService()在Activity()中调用的,其他为Service()里面的方法。
- 第二种方式是使用bindService()方法来绑定运行Service,使用unbindService()来解绑停止Service()。使用此方法更加复杂一些,bindService()参数有三个,分别为intent,serviceConnection和常数。一般需要新建一个ServiceConnection来进行连接。 此处注意: unbindService()只执行一次,解绑后再次调用unbindService()方法会报错。执行过程:bindService()——>onBind()——>onUnbind()——>unbindService()——>onDestory()。
- 此外,两种方式可以混合一起使用,当一起使用时,如果启动Service的方法即使用startService()用使用了bindService()那么,停止服务时也必须搭配使用stopService()和unbindService()方法。
2. service的具体实现
- 第一步:新建一个MyService 继承Service类,并覆写onStartCommand方法。
- 第二步:启动Service,使用startService()或者bindService()方法。
- 第三步:调用停止Service的方法。
3. 使用bindService()方法来实现与Service()之间的通信
要实现Context与Service通信,需要使用bindService()方式启动Service()。下面以一个简单的下载服务为实例回顾一下Service()通信的具体流程。
- 第一步:需要新建MyService()继承Service基类,覆写onBind()方法。
- 第二步:在MyService()类中新建MyBinder内部类,继承Binder基类。在此类中定义自己的方法,此处定义两个方法:startDownload(),getProgress()方法,分别用来启动下载和获取下载进度。
- 第三步: 在MyService()类中的onBind()方法中返回一个Mybinder类的实例。这个实例会在前台定义ServiceConnection类中的onServiceConnected中作为方法参数传递到前台。前台可以通过此类对象调用MyBinder类中的方法。
- 第四步:在前台首先定义一个ServiceConnection类,覆写onServiceConnected()方法,在此方法中获取实例MyBinder类实例,并调用它的.startDownload()和.getProgress()方法。
- 第五步:调用bindService()方法,传递参数为intent,connection,BIND_AUTO_CREATE 。且解绑参数是传递ServiceConnection实例即可。
以下为代码实例:
MyService.class
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
public class MyService2 extends Service {
public MyService2() {
}
class MyBinder extends Binder {
//定义两个方法,会传递到前台被调用
public void startDownload() {
//开启下载
}
public int getProgress() {
return 0;
}
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
//此方法里面是使用startService()方法之后执行的,且不做交互
return super.onStartCommand(intent, flags, startId);
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
}
Main2Activity.class
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
public class Main2Activity extends AppCompatActivity {
private Button mButton;
private Button mStopService;
private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
MyService2.MyBinder mBinder = (MyService2.MyBinder) iBinder;
mBinder.startDownload();
mBinder.getProgress();
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
//断开连接,回收资源
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
mButton = (Button) findViewById(R.id.start_service);
mStopService = (Button) findViewById(R.id.stop_service);
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//绑定Service()
Intent intent = new Intent(getApplication(), MyService2.class);
bindService(intent, mConnection, BIND_AUTO_CREATE);
}
});
mStopService.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
unbindService(mConnection); //解绑,直接传递ServiceConnection即可,不必要传递Intent
}
});
}
}
接下来,我们学习了前台服务。前台服务和后台服务相比,优先级更高,不易于被系统回收而杀死。前台服务的一个特点就是,在手机通知栏会显示一个服务的通知,像音乐播放器、下载进度等。下面来学习一个简单的前台服务。
4. 前台服务
只需要将一个Activity绑定到一个Service中就可以得到前台服务。新建Intent,将Intent放入PendingIntent中,然后新建Notification notification=new NotificationCompat.Builder(this).set()….setContentIntent(pi)等参数。之后使用startForeground(1,notification)方式启动即可。
5. IntentService介绍
我们一般使用Service,都需要做一些耗时任务。然而Service也是运行在UI线程里面的,因此一般需要在Service里面开启线程。然而,很多时候,我们开启线程之后,很容易忘记去关闭线程,而且使用起来也比较麻烦。所以Android推出了IntentService类,继承的Service。主要是用来结果我们这个问题的。
IntentService中自带有一个抽象方法需要覆写onHandIntent()方法,此方法都是执行在子线程中的,且代码执行完后会自动结束。这些是IntentService底层封装好的。
注意: 在调用startService(IntentService)后,onHandIntent()会执行多次,以消息队列的方式依次执行。
Service和IntentService基础就介绍到这里,下面通过一个具体的下载实例来复习和巩固知识点。