Android学习笔记 Service(part.2)

本文详细介绍了Android中的IntentService、BindService以及AIDL实现跨进程服务。讲解了IntentService的工作原理,如何创建和使用;阐述了BindService的生命周期、绑定过程以及不同类型的绑定服务。同时,还探讨了AIDL的基本概念、数据类型支持和使用案例。此外,还涵盖了MediaPlayer的常用方法以及Timer定时器的使用。

Day14 Service

  • IntentService
  • BindService
  • AIDL实现跨进程服务
  • MediaPlayer
  • Timer

IntentService

IntentService是继承于Service并处理异步请求的一个类,在IntentService内有一个工作线程来处理耗时操作,启动IntentService的方式和启动传统Service一样,同时,当任务执行完后,IntentService会自动停止,而不需要我们去手动控制。
另外,可以启动IntentService多次,而每一个耗时操作会以工作队列的方式在IntentService的onHandleIntent回调方法中执行,并且,每次只会执行一个工作线程,执行完第一个再执行第二个,以此类推。


  • 关键方法
  • 注意事项

关键方法

除其他Service生命周期方法外:
* ==onHandleIntent(Intent)==
在该方法中进行耗时操作,由IntentService中封装的异步任务完成

处理异步请求的IntentService,其内有一个工作线程来处理耗时操作
内部使用了单线程池模式(所以每次只执行一个任务,完成后再进行第二个)

注意事项

创建IntentService子类时,需要提供一个==无参==的构造方法且调用:
==super(null)==


BindService

基于IBinder方式将两个组件进行绑定,然后相互传值.
如果以绑定的方式启动的服务,在解除绑定时也会自动停止服务.
需创建自定义Binder子类并通过onBind()返回

  • 生命周期方法
  • 使用步骤
  • 绑定类型

生命周期

除其他Service生命周期方法外:

  • ==IBinder onBind(Intent)==
    • 返回自定义的Binder的子类
    • 返回Messenger的getBinder()
  • ==onUnBind(Intent)==
    • 解除绑定时回调
  • ==onReBind(Intent)==
    • 重新绑定时回调
使用步骤

bindService的过程:
* 在Service组件中,声明Binder类的子类(公共),在其子类中声明组件之间的接口方法
* 在onBind()方法中,实例化Binder子类的对象,并返回
* 在绑定服务组件端(Activity),实例化ServiceConnection接口对象
* 在ServiceConnection接口对象的onServiceConnected()方法中,将方法的第二个参数IBinder对象强转成Binder子类对象
* 在适当的位置 调用 Context.bindService()来绑定服务。


创建类,继承Service,并现实onBind()方法

在Service组件中,声明Binder类的子类(公共),在其子类中声明组件之间的接口方法

    public class MyService extends Service{
        public IBinder onBind(Intent intent) {
            ...
        }

        public class MyBinder extends Binder{
            public void MyMethod1(){
                ...
            }
            public void MyMethod2(){
                ...
            }
            ...
        }
    }

在onBind()方法中,实例化Binder子类的对象,并返回

    @Override
    public IBinder onBind(Intent intent) {
        return new MyBinder();//实例化Binder的子类,并返回
    }

在绑定服务组件端(Activity),实例化ServiceConnection接口对象
在ServiceConnection接口对象的onServiceConnected()方法中,将方法的第二个参数IBinder对象强转成Binder子类对象

    ServiceConnection conn=new ServiceConnection(){
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            // 绑定成功的方法
            myBinder=(MyBinder) service;
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            // 与绑定服务组件断开连接(发生的时机:由于系统原因造成了服务组件停止或销毁)
            myBinder=null;
        }
    };

在适当的位置 调用 Context.bindService()来绑定服务。

    //绑定服务组件
    bindService(new Intent(getApplicationContext(),TimerService.class),
                conn, BIND_AUTO_CREATE);

    //BIND_AUTO_CREATE标识表示:绑定的服务组件如果不存,则会自动创建,
    //注:由bindService方式启动的Service,其生命周期会受到绑定组件的影响,即当绑定组件Activity销毁时,Service也会停止

解除绑定

    //解除绑定
    Context.unBindService(Intent)
绑定类型

绑定服务的类型:
* ==BIND_AUTO_CREATE==
- 绑定的service不存在时,会自动创建
* ==BIND_ADJUST_WITH_ACTIVITY==
- service的优先级别与根据所绑定的Activity的重要程度有关,Activity处于前台,service的级别高
* ==BIND_NOT_FOREGROUND==
- Service永远不拥有运行前台的优先级
* ==BIND_WAIVE_PRIORITY==
- Service的优先级不会改变
* ==BIND_IMPORTANT | BIND_ABOVE_CLIENT==
- 所绑定的Activity处于前台时,Service也处于前台
- BIND_ABOVE_CLIENT 指定内存很低的情况下,运行时在终止绑定的Service之前终止Activity


AIDL实现跨进程服务

一种接口定义语言,用于约束两个进程间的通讯规则,供编译器生成代码

个人理解:
为了能使两个进程(应用)之间通信,二者需要持有同一个通讯工具,即通过AIDL文件定义的接口
当一个应用使用AIDL文件时,会自动生成其定义的java接口,通过这个接口实现与目标服务的通信接驳

  • AIDL支持的数据类型
  • 使用方法案例
AIDL支持的数据类型

AIDL默认支持的类型:

  • java基本类型:==int==、==long==、==boolean==、==float==、==double==、==char==
  • 引用类型及集合:==String[]==、==List==、==Map==
使用方法案例
使用步骤概览

服务端:
- 服务端创建.aidl文件和声明接口
- 创建类,继承Service,并实现onBind方法
- 在Service类中定义aidl中声明接口的Stub对象,并实现aidl接口中声明的方法
- 在onBind方法中返回Stub对象
- 在AndroidManifest.xml中注册Service并声明其Action

客户端:
- Context.bindService(new Intent(接口的类名,ServiceConnection,int)
- 定义ServiceConnection对象

    onServiceConnected(ComponentName,IBinder)
    onServiceDisconnected()
    //aidl接口对象=AIDLService.Stub.asInterface(server)
  • 在Activity定义aidl接口对象
样例

IRemoteService.AIDL

    package com.qf.aidl;

    interface IRemoteService{

    void print(String msg);

    String getName();
}
  • RemoteService.java
    public class RemoteSerice extends Service {
    //2.1 实例化.aidl接口的Stub对象
    private IRemoteService.Stub stub=new IRemoteService.Stub() {
        @Override
        public void print(String msg) throws RemoteException {
            Log.i("debug", "--RemoteSerice---"+msg);
        }
        @Override
        public String getName() throws RemoteException {
            return "RemoteSerice";
        }
    };
    @Override
    public IBinder onBind(Intent intent) {
        return stub;//2.2 返回aidl接口的Stub对象
    }
}
  • (Client)
        //声明aild接口对象
    IRemoteService remoteService;

    //实例化绑定组件之间的通信接口
    ServiceConnection conn=new ServiceConnection() {

        @Override
        public void onServiceDisconnected(ComponentName name) {
            // TODO Auto-generated method stub

        }

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            //将第二个参数转化为.aidl接口对象
            remoteService=IRemoteService.Stub.asInterface(service);
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //绑定其它应用的Service组件,在绑定成功之后,将返回的Stub对象转化为aidl接口对象
        bindService(new Intent("com.qf.serivce04_aidl_server.RemoteSerice"),
                conn, BIND_AUTO_CREATE);

    }

MediaPlayer

用于播放音乐和视频文件

构造方法:==MediaPlayer()==

通过静态方法(create)构造会直接进入prepared状态

通过静态方法构造:==MediaPlayer create(Context context, int resid)==

常用方法
  • ==setDataSource(String path)== 设置媒体源
  • ==setLooping(boolean)== 设置是否循环播放
  • ==prepare()== 预处理,调用start()前必须先调用此方法
  • ==start()== 开始播放
  • ==pause()==暂停播放
  • ==stop()== 停止播放
  • ==isPlaying()== 是否正在播放
  • ==reset()== 重置播放器,进入idle空闲状态
  • ==release()== 释放资源
  • ==getDuration()== 获取播放文件的总时长,单位:毫秒
  • ==getCurrentPosition()== 获取当前播放的位置
  • ==seekTo(int position)== 定位到指定的播放时间

Timer定时器

按排一段定时任务在指定的时间执行,对于提醒相关的任务,应该设置重复间隔时间

关键方法
  • ==schedule(TimerTask task, Date when)== 按排任务在指定时间执行
  • ==schedule(TimerTask task, long delay)== 按排任务延迟多少毫秒之后执行
  • ==schedule(TimerTask task, long delay, long period)== 按排任务在延迟多个毫秒后执行,并间隔多少毫秒后重复
  • ==cancel()== 取消定时器
TimerTask 定时任务

TimerTask 定时任务类,是实现Runnable接口的抽象类

样例
    timer.schedule(new TimerTask(){
        @Override
        public void run() {
            // TODO 在指定的时间执行的任务

            NotificationCompat.Builder builder=
                    new NotificationCompat.Builder(getApplicationContext());
            builder.setSmallIcon(android.R.drawable.ic_menu_today)
                    .setContentTitle("提醒")
                    .setContentText("时间了,该起床了....")
                    .setTicker("时间了,该起床了....")
                    .setDefaults(Notification.DEFAULT_SOUND)
                    .setOngoing(true);

            notifyMgr.notify(2, builder.build());
        }
    },10*1000, 5*1000);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值