Service用法概述

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()
当绑定之后只有解除绑定,非绑定的服务才能销毁

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值