1.service分类:运行在主线程中
绑定服务与非绑定服务
区别:
非绑定的服务能给service传值,service不能给activity传值
与调用者无关联,调用者退出,服务仍可运行
绑定的服务service能给activity传值
与调用者有关联,调用者退出,服务也退出
2.服务的生命周期的五个方法:
//创建,只会被执行一次
onCreate()
//服务被创建之后执行(执行服务的逻辑,例如下载文件,播放音乐等)
onStartCommand(Intent intent, int flags, int startId)
//绑定服务执行的方法(通过IBinder可以使 服务器向activity传值)
onBind(Intent intent)
//解除绑定执行的方法
onUnbind(Intent intent)
//销毁服务
onDestroy()
3.非绑定服务的使用:
使用步骤:
* 1.写一个类继承service,实现必须重写的onBind(Intent intent)方法;
重写onStartCommand(Intent intent, int flags, int startId)方法。执行服务的逻辑,如:下载文件,播放音乐
* 2.在清单文件中注册
* 3.通过Intent开启服务与传值(非绑定的方式开启)
Intent intent = new Intent(MainActivity.this, MyService.class);
//通过意图给服务传值(但是绑定服务不能给activity传值)
intent.putExtra(“play”,”哈哈哈哈”);
* 4.开启服务
startService(intent);
* 5.停止服务
stopService(intent);
非绑定服务的生命周期:
* 1.开启服务执行的方法
* onCreate()
* onStartCommand()
* 当服务已经开启,再次开启的时候,不执行onCreate(),只执行onStartCommand()
* 如果不调用stopService()方法,服务将一直在后台运行
* 2.停止执行的方法
* onDestroy()
4.绑定服务的使用:
使用步骤:
* 1.创建服务,写一个类继承Service,实现重写的onBind()方法
重写onBind(Intent intent)方法,返回IBinder对象,利用该对象向activity传值
重写其他的方法查看生命周期
* 2.在清单文件中注册
* 3.通过bindService开启绑定服务,将三个参数传入:
bindService(intent,serviceconnection,int flag)
参数说明:
* 参数1:intent;
* 参数2:ServiceConnection传值的桥梁;一般写一个内部类实现ServiceConnection接口,声明内部类将对象传入
或者直接new ServiceConnection()实现重写的方法
* 参数3:flag服务标志位,一般设置为BIND_AUTO_CREATE;
* 4.解除绑定:unbindService(myConnection);
* 5.进行和activity交互传值
在service中重写onBind(Intent intent)方法,返回IBinder对象,利用该对象向activity传值
a:写一个内部类继承Binder,在该内部类里面自定义方法return 值;
b:声明该内部类对象,在onBind(Intent intent)方法中return 该对象
通过a,b方法就能通过绑定服务将service的值传给activity了。
代码如下:
private MyIBinder myIBinder = new MyIBinder();
@Override
public IBinder onBind(Intent intent) {
Log.e("---", "onBind");
return myIBinder;
}
/**
* 以绑定开启的服务,需要创建一个binder的返回对象
* 可以写携带的数据,也可以把当前的服务带回activity
*/
class MyIBinder extends Binder {
//自己写的,返回当前service
MyService getService(){
return MyService.this;
}
//如果返回为一个String类型的值,可以写一个String类型返回值的方法
String getStringData(){
return "hahahah";
}
}
在Activity中得到service传归来的值:在ServiceConnection传值的桥梁中来获得
写一个内部类实现ServiceConnection接口实现两个重写的方法:
onServiceConnected(ComponentName name, IBinder service):接收服务传回来的值
onServiceDisconnected(ComponentName name):当服务被异常kill的时候调用的方法
代码如下:
class MyConnection implements ServiceConnection {
//接收服务传回来的值
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
//从服务里面拿回值(得到回传过来的服务)
//强制转换成IBinder对象6
myIBinder = (MyService.MyIBinder) service;
//得到service
myService = myIBinder.getService();
//得到String类型数据
String data = myIBinder.getStringData();
Log.e(“—”,”binderData:”+data);
}
//当服务被异常kill的时候调用的方法
@Override
public void onServiceDisconnected(ComponentName name) {
}
}
绑定服务的生命周期:
* 绑定服务启动调用的方法
* onCreate()
* onBind()
* 注意:只会创建一次,绑定一次,不会重复绑定
* 解除绑定调用的方法:
* onUnbind(Intent intent)
onDestory()
5.服务中进行耗时操作的两种方式:(IntentService)
IntentService使用队列的方式将请求的Intent加入队列,然后开启一个worker thread(线程)来处理队列中的Intent,对于异步的
startService请求,IntentService会处理完成一个之后再处理第二个,每一个请求都会在一个单独的worker thread中处理,不会阻塞应用
程序的主线程。
(1)在服务中开启一个线程执行耗时操作
步骤:
a:写一个类继承Service;实现重写的方法
b:在清单文件中注册
b:根据启动模式重写相应方法,在方法中开启线程执行耗时操作,
可以将下载的数据保存在sdCard中
1)非绑定启动
onCreate()
onStartCommand(Intent intent, int flags, int startId);线程操作在此进行
onDestory()
2)绑定启动
onBind(Intent intent)
onUnBind()
onDestory()
c:在主线程中读取SDCard中的数据,显示在UI上
(2)IntentServie;里面封装了一个Thread
步骤:
a:写一个类继承IntentService,实现重写的方法onHandleIntent(Intent intent)
在这个方法中执行耗时操作
//下载的逻辑代码
@Override
protected void onHandleIntent(Intent intent) {
byte[] data = HttpURLConnHelper.loadByteFromURL(path);
boolean flag = SDCardHelper.saveFileToSDCardPublicDir(data, Environment.DIRECTORY_DOWNLOADS, “haha.jpg”);
}
b:注意必须有一个空的构造方法(将实现的构造方法,改为空的构造方法)
6.Activity、Service、BroadCastReceiver之间的通信
在主界面上,启动后台服务Service,后台处理数据,前台通过BroadcastReceiver获得数据并更新UI。
在Service中通过启动广播将数据发送到Activity中步骤:
//a:创建服务,写一个类继承IntentService,实现重写的onHandlerIntent(Intent intent)方法,并在清单文件中注册service
在此方法中执行耗时操作
//b:在service中执行完操作后,通过Intent发送广播(设置action,发送广播)
//设置广播的action
Intent intent1 = new Intent("com.sendValue.value");
intent1.putExtra("value",value);
sendBroadcast(intent1);
//c:在Activity中通过Intent开启服务
//开启服务
Intent intent = new Intent(MainActivity.this, LoadService.class);
startService(intent);
//d:在Activity中动态注册广播(注意action要和service中发送过来的action一致),在onReceive()方法里面接收到值
//通过写一个内部类继承BroadcastReceiver实现onReceive(Context context, Intent intent)方法,来动态注册广播
//动态注册广播
intentFilter = new IntentFilter();
intentFilter.addAction("com.sendValue.value");
//注册广播
registerReceiver(myBroadCast, intentFilter);
//获得service通过广播发送过来的数据,进行UI更新
class MyBroadCast extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//接收到动态的值
int data = intent.getIntExtra("value",1);
textView.setText(""+data);
}
}
//e:在onDestroy()方法中解除广播的注册
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(myBroadCast);
}
Demo:Activity
/**
* 案例:服务里面一直执行下载操作然后需要把下载的值传回activity中
* 步骤:
* 1.创建服务并且实现逻辑
* 2.在服务执行逻辑的时候将值传到广播上
* 3.在activity里动态注册广播,在onReceive()方法里面接收到值
*/
public class MainActivity extends AppCompatActivity {
private TextView textView;
private MyBroadCast myBroadCast;
private IntentFilter intentFilter;
private LoadService loadService;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.text);
myBroadCast = new MyBroadCast();
loadService = new LoadService();
//开启服务
Intent intent = new Intent(MainActivity.this, LoadService.class);
startService(intent);
//动态注册广播
intentFilter = new IntentFilter();
intentFilter.addAction("com.sendValue.value");
//注册广播
registerReceiver(myBroadCast, intentFilter);
}
//广播的内部类
class MyBroadCast extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//接收到动态的值
int data = intent.getIntExtra("value",1);
textView.setText(""+data);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(myBroadCast);
}
Manifest.xml清单文件中:
Service中:
/**
* Created by niutingting on 2016/2/19 0019.
*/
public class LoadService extends IntentService {
//模拟下载进度的值
int value = 0;
/**
* Creates an IntentService. Invoked by your subclass's constructor.
*/
public LoadService() {
super("name");
}
@Override
protected void onHandleIntent(Intent intent) {
//网络逻辑在这里执行
while (true) {
try {
Thread.sleep(1000);
value++;
} catch (InterruptedException e) {
e.printStackTrace();
}
//设置广播的action
Intent intent1 = new Intent("com.sendValue.value");
intent1.putExtra("value",value);
sendBroadcast(intent1);
}
}
}
7.注意:
当开启服务并且开启了绑定服务
生命周期:
onCreate()
onStartCommand(Intent intent, int flags, int startId)
onBind(Intent intent)
onUnbind(Intent intent)
onDestroy()
当绑定之后只有解除绑定,非绑定的服务才能销毁