Android四大组件之Service

一、特点:

这里写图片描述

1.  是Android的四大组件之一
2.  有生命周期方法
3.  可以在长期在后台进行操作的类
4.  是Context的子类

二、常见作用 :

1.  音乐播放器,可以在服务类中控制并处理音乐的播放
2.  长期在后台下载的操作,如:全选下载40集电视剧
3.  长期在后台处理一些监控类的事情

三、使用方式:

  • 开启服务

    通过startService方法启动的服务就叫做开启的服务
    
  • 特点

    1.  即使程序退出,服务也不会销毁
    2.  无法得到被启动的Service对象
    
  • 使用步骤

    1.  创建一个Service的子类
    2.  清单文件中注册此子类
    
<!--
        注册Service
        android:name  用于注册Service子类的具体路径
        -->
        <service android:name=".MyService"/>

或者:

<!--
        在注册service时,也可给当前service配置action动作名称
        稍后通过startservice或者bindservice方法启动服务时
        可以直接将该action名称传递intent对象
        -->
        <service android:name=".MusicService"
            >
            <intent-filter>
                <action android:name="com.music"/>
            </intent-filter>
        </service>
3.  在Service的子类中重写onStartCommand方法
/*
    参数1:通过startService方法传递过来的Intent对象,用于携带数据
    参数3:给本次启动的服务操作分配一个id标识,简单来说,也可表示时第几次调用了startService方法
    参数2: 用于判断本次启动的服务时正常启动的还是系统自动重启的
            通常情况下,当正常通过startService方法启动服务时,flags为0
            当服务被系统意外回收后,当系统再次自动重启时,flags标识不为0
            自动重启时,如果返回值为START_STICKY或者START_STICKY_COMPATIBILITY,那么flags的值为:START_FLAG_RETRY
             自动重启时,如果返回值为START_REDELIVER_INTENT,那么flags的值为:START_FLAG_REDELIVERY


     返回值:  当服务被系统意外回收后,是否要让当前服务具备自动重启的能力

     START_NOT_STICKY    不会自动重启

     START_STICKY 会自动重启,当重启的时候,参数intent对象中不携带数据
     START_STICKY_COMPATIBILITY  会自动重启,参数intent对象中不携带数据,是START_STICKY的兼容版本,不保证会重启成功
     START_REDELIVER_INTENT  会自动重启,参数intent对象中也会携带数据
     */
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.i(TAG, "onStartCommand: "+this.hashCode());

        //取出在调用startService方法时传递的数据
//        String data = intent.getStringExtra("data");
//        Log.i(TAG, "onStartCommand: "+data +"   "+startId);

        Log.i(TAG, "onStartCommand: "+flags);
        return START_REDELIVER_INTENT;
    }
  • 生命周期:
    这里写图片描述

  • 生命周期方法的运行特点:

    1.  当第一次调用startService方法时,运行onCreate—onStartCommand生命周期
    2.  当后期重复调用startService方法时,只运行onStartCommand方法,并且重复运行时Service类始终用的是同一个对象
    3.  当页面退出时,不会onDestroy方法
    4.  当服务通过stopService方法或者stopSelf方法时调用onDestroy方法时才会运行onDestroy方法。
    

三、绑定服务的使用方式:

  • 绑定服务

    通过bindService方法启动的服务叫做绑定的服务
    
  • 特点

    1.  绑定的服务当页面退出后会自动解除绑定
    2.  当服务绑定后,通过指定方式可以在页面中直接调用服务中的方法,服务和页面之间的数据传输会比较方便
    
  • 使用方式

    1.  创建Service的子类
    2.  清单文件中进行子类的注册
    3.  重写Service中的生命周期方法
    

这里写图片描述

4.  调用bindService方法绑定服务
 /*
                参数:
                1. Intent对象,用于秒数要绑定的是哪个服务对象
                2. ServiceConnection接口,
                3. flag标识,用于设置要绑定的Service对象的创建特点
                最常用:Context.BIND_AUTO_CREATE
                当要绑定服务对象,先判断系统中是否已经存在服务对象,如果已经存在,直接绑定此对象
                如果不存在,那么先创建服务对象,然后在进行绑定操作
                 */
                bindService(new Intent(this,MyBindService.class),
                        conn,
                        Context.BIND_AUTO_CREATE);
5.  修改onBind方法的返回值
/*
    返回值:
    当返回值为null时,绑定操作运行到此结束,绑定失败
    只有当返回值不为null时,继续运行ServiceConnection接口中的onServiceConnected方法,绑定成功
     */
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        Log.i(TAG, "onBind: ");
        return new MyBinder();
    }

 //Binder是系统提供的IBinder接口的实现子类
    /*
    该类的作用:将想要开放给页面中调用的方法定义到此类中
     */
    class MyBinder extends Binder {

        public int sum (int n1,int n2){
            return  n1+n2;
        }

    }
6.  在页面的onServiceConnected方法中获取onBind方法的返回值对象,通过此对象调用服务中的方法即可
        //初始化接口对象
        conn = new ServiceConnection() {
            //当页面和服务成功绑定后调用的方法
            /*
             参数2:就是onBind方法的返回值
             */
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                Log.i("oye", "onServiceConnected: ");
                mb = (MyBindService.MyBinder) service;
            }

            //当服务被系统意外关闭,页面和服务断开连接后调用的方法
            @Override
            public void onServiceDisconnected(ComponentName name) {

            }
        };
  • 按钮的点击事件中:
 case R.id.button3:
                if (mb != null) {
                    int num = mb.sum(4,5);
                    Log.i("o", "click: 运算的结果为 :  "+num);
                }

                break;
  • 解除绑定:
 // 注意此方法不要多次调用
                //也不要在没有运行bindService情况下调用此方法
                unbindService(conn);

四、IntentService服务的使用方式:

  • 作用

    • 当需要Service长期在后台进行下载操作(或其他耗时操作时),由于Service中的代码默认运行在主线程,因此不能够直接的在Service中进行连网操作。
  • 解决方式:

    1.  通过属性解决,即将Service中的代码分配在其他进程中运行。
    
  <service android:name=".MyIntentService"
        android:enable="true"
        android:process="remote"/>

2.  通过在Service中启动子线程,在子线程中进行耗时操作

3.  在通过startService方法启动服务时,直接启动一个IntentService的子类,因该子类中的onHandleIntent方法中的代码默认运行在子线程中。
  • 特点:

    1.  IntentService的子类只能通过startService方法启动,不能配合bindService方法使用
    2.  当onHandleIntent方法中的代码执行完毕后,当前Service会自动销毁
    
  • 使用方式:

    1.  创建一个IntentService的子类
    2.  在清单文件中进行注册
    3.  在子类中重写onHandleIntent方法,在该方法中处理耗时的操作
    
 /**
     * 创建子类后,手动修改构造方法
     * 将构造方法的参数列表清空掉
     * 在super()中添加任意的字符串参数
     * 此参数的作用为:给IntentService中自带的子线程起一个名字
     */
    public MyIntentService() {
        super("ayy");
    }
 /*
    该方法中的代码默认运行在子线程中,
    当调用startService启动当前服务后,会运行此方法
    参数中的Intent就是startService方法中传递的Intent对象
     */
    @Override
    protected void onHandleIntent(Intent intent) {
        Log.i("oye", "onHandleIntent: "+Thread.currentThread().getName());
        String url = intent.getStringExtra("url");
        try {
            HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
            conn.setRequestMethod("GET");
            conn.connect();

            if (conn.getResponseCode()  == 200) {
                InputStream is = conn.getInputStream();

                Bitmap bitmap = BitmapFactory.decodeStream(is);
                ByteArrayOutputStream bos = new ByteArrayOutputStream();

                bitmap.compress(Bitmap.CompressFormat.PNG,100,bos);

                SystemClock.sleep(5000);
                //获取图片数据对应的byte数组
                img = bos.toByteArray();

            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
 /**
     * 当onHandleIntent方法中的耗时操作执行结束后,当前的IntentService会自动销毁
     * 一旦销毁,就会运行onDestroy方法
     */
    @Override
    public void onDestroy() {
        Log.i("oye", "onDestroy: 图片下载结束");
        Intent data = new Intent("com.intent.img");
        data.putExtra("img",img);
        sendBroadcast(data);
        super.onDestroy();
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值