Service用法概述

来源:互联网 发布:调节阀选型计算软件 编辑:程序博客网 时间:2024/06/02 04:14

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;@Overrideprotected 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 {@Overridepublic void onReceive(Context context, Intent intent) {//接收到动态的值int data = intent.getIntExtra("value",1);textView.setText(""+data);}}@Overrideprotected 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()
当绑定之后只有解除绑定,非绑定的服务才能销毁

1 0