Android中的Service

  • 什么是Service
  • Service有哪些应用场景
  • startService方式启动Service怎么做
  • bindService方式启动Service怎么做
  • IntentService有什么不同
  • IntentService怎么用,注意事项

什么是Service

Service是Android系统中的四大组件之一,它是一种长生命周期的,没有可视化界面,运行于后台的一种服务程序。

Service的应用场景

Service就是一种运行在后台的组件,甚至从始至终用户都不需要和它进行交互,比如Service可以处理一些网络事物,播放音乐,I/O文件传输,或者和Content provider交互。如果需要注意的是,一个Service运行在它宿主线程的主线程上,Service不会自己创建一个新的线程,也不会在一个独立的线程上运行(除非你指定它),也就是说如果你要用Service来执行大量的占用CPU的操作,或者是运行耗时的阻塞操作,例如后台播放MP3,或者网络事物,那么你就应该创建一个新的线程来实现Service去完成这些任务,通过创建新的线程,你降低ANR(Application Not Respond)的风险,不影响主线程保持与用户的交互。

线程和Service就有一定的相似性,到底什么时候用Service,什么时候用Thread呢?

在Google官方文档里这样写:如果你需要在主线程之外来完成你的任务,但只发生在在用户与当前Application进行交互的时候,就创建线程来实现它,而不是Service。比如说,如果你想播放音乐,但是只想在当前Activity运行的时候,如果当前Activity死掉了,那么也就停止播放,你可以在onCreate()中创建新的线程,在onStart()中开始运行线程,然后在onStop()中停止这个线程。你也可以考虑用异步加载AsyncTask或者HandlerThread的方式来代替传统的线程。谨记一个Service是在当application的主线程上跑,如果要进行大量的操作,那么就创建一个新的线程来实现Service。

startService方式启动Service

一般在不需要交互的情况下用startService()来启动服务。

  • 继承Service
public class MusicService extends Service
  • 重写onCreate方法
    Service在创建时调用的方法,可以用来做数据初始化,Service在没有停止之前,只会执行一次。

  • 实现onBind方法
    由于Service是一个抽象类,定义了一个onBind抽象方法,所以必须实现此抽象方法,return null 即可,此方法在startService方式用不上,无需理会。

  • 重写onStartCommand方法
    Service创建后会调用onStartCommand,此方法中可以接收调用者传递过来的参数,并且可以编写需要的逻辑代码,当重复调用Service时,onStartCommand会重复执行,onStart方法已弃用。

  • 重写onDestroy方法
    Service在退出时调用,此方法中可以编写释放资源的操作。

  • 在AndroidManifest文件中注册Service

<service android:name="com.lenovo.mymediaplayer.service.MusicService" >
</service>

在onStartCommand()中接受Intent ;

Intent intent = new Intent(this, HelloService.class);
startService(intent);

bindService方式启动Service

  • 先创建一个类继承Service
public class MyBindService extends Service {
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
}
  • 然后创建一个内部类MyBinder继承Binder,创建一个方法返回服务的对象
public class MyBinder extends Binder{
        public MyBindService getService(){
            return MyBindService.this;
        }
    }
  • 实例化这个内部类
private MyBinder myBinder = new MyBinder();
  • 返回myBinder
 public IBinder onBind(Intent intent) {
        return myBinder;
    }
  • 创建一个方法
 public void run(){
        new Thread(new Runnable() {
            @Override
            public void run() {
                int count = 0;
                while (count < 10) {
                    Log.e(TAG, "run: -------" + count);
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    count++;
                }
            }
        }).start();
    }
  • 接下来我们将Activity中的代码完善,首先我们要实例化一个ServiceConnection用于绑定服务
  private ServiceConnection connection = new ServiceConnection() {
        /**
         * Service连接成功时调用
         * @param name
         * @param service
         */
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.e(TAG, "onServiceConnected: -------------------");
            //获取Service返回的MyBindService对象
            MyBindService myBindService  = ((MyBindService.MyBinder)service).getService();
            //调用MyBindService的run方法
            myBindService.run();
        }

        /**
         * Service因为一些原因被破坏或销毁的时候调用
         * @param name
         */
        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.e(TAG, "onServiceDisconnected: ---------------------------" );
        }
    };
  • 然后在点击事件中创建服务,这里使用bindService,一个参数是Intent,第二个参数就是刚刚实例化的ServiceConnection,第三个是创建方法,这里我们使用BIND_AUTO_CREATE
Intent intent = new Intent(this,MyBindService.class);
bindService(intent,connection,BIND_AUTO_CREATE);
  • 解绑使用unbindService
unbindService(connection);

IntentService有什么不同

  • IntentService是一个基于Service的一个类,用来处理异步的请求,我们可以通过startService(Intent)来提交请求,该Service会在需要的时候创建,当完成所有的任务以后自己关闭,下面我们来看看IntentService的用法。
  • 创建一个MyIntentService继承IntentService,同时创建一个构造方法,这里需要注意,默认的重构方法是有参的,而在AndroidManifest.xml中注册时,需要你有一个无参的构造方法,所以这里我们可以将参数删掉,将名字指定为服务类名,同时它需要你重写onHandleIntent方法,这里我们依旧写一个0-9循环。
public class MyIntentService extends IntentService {
    private String TAG = "MyIntentService";

    /**
     * Creates an IntentService.  Invoked by your subclass's constructor.
     *
     * @param name Used to name the worker thread, important only for debugging.
     */
    public MyIntentService() {
        super("MyIntentService");
    }

    @Override
    protected void onHandleIntent(@Nullable Intent intent) {
        int count = 0;
        while (count<10){
            Log.e(TAG, "onHandleIntent: ------------"+count );
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            count++;
        }
    }
}
  • 然后在Activity中通过startService启动这个服务
Intent intent = new Intent(this,MyIntentService.class);
startService(intent);

可以看到,我们执行了一个while循环耗时操作,但是并没有写在子线程中,这是因为它会自己创建子线程进行处理,并且它是串行的,也就是当前这个线程执行完毕才会执行下一个线程

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值