为了账号安全,请及时绑定邮箱和手机立即绑定

Android四大组件之Service(一):Service概述及创建与销毁

标签:
Android

对于Android的四大组件的Service, Broadcast Receiver和ContentProvider一直不太熟悉,因此在观看相关视频时将一些笔记记录下来,便于之后的学习。

Service是能够在后台执行长时间运行操作并且不提供用户截脉呢的应用程序组件。其他的程序组件可以启动Service,并且在用户退出该应用程序时,Service仍然可以继续执行。另外,其他组件可以与Service绑定来进行组建之间的通信,甚至进行进程间的通信(IPC)。例如Service可以在后台处理网络事务,播放音乐等等。

使用Service首先创建继承自Service的类(也可以继承自IntentService类,本人不太了解,暂不介绍),然后同Activity一样需要在AndroidMenifest文件中进行申明。

//我们这里定义了EchoService继承自Service,需要复写onBind()方法。
public class EchoService extends Service{
    @Override
    public IBinder onBind(Intent arg0) {
        //当方法调用时打印输出
        System.out.println("EchoService---onBind");
        return null;
    }
}
//在AndroidMenifest.xml文件中<application>标签下申明Service
 <service android:name=".EchoService"></service>

在Service中主要有下面几个方法

onStartComand():
    在其他组件用startService()方式来启动Service时,会调用该方法
onBind():
    当组件使用bindServiced()方式来与Service绑定时,调用该方法。
onCreate():
    当Service第一次创建时,调用该方法。(在调用onStartCommand(),onBind()之前调用),如果Service已经运行,该方法不被调用
onDestroy():
    当Service不再使用时调用该方法,Service应该实现该方法清理线程,注册监听器,接受者等资源。这是Service最后收到的调用。

下面是一些需要注意的方面

1.在其他组件使用startService()的方式启动Service时,先调用onCreate(),然后调用onStartCommand(),在Service任务结束后,需由该组件使用stopService()来结束Service,此时会调用onDestroy()。
2.Service未运行时,在其他组件使用bindServiced()方式来与Service绑定时,会先调用onCreate(), 再调用onBind(),在Service任务结束后,需由该组件使用unBindService()来结束Service,此时会调用onDestroy()。
3.Service已经运行时,在其他组件使用bindServiced()方式来与Service绑定时,不会调用onCreate(), 而是直接调用onBind(),在Service任务结束后,需由该组件使用unBindService()来结束Service,此时不会调用onDestroy(),需要组件使用stopService()来关闭Service,此时才会调用onDestroy()。

图片描述
我们创建四个Button,图中前四个,分别调用startService(),stopService(),bindService(),unBindService()方法

Intent intent = new Intent(this, EchoService.class);
public void onClick(View v) {
    switch(v.getId()){
    case R.id.btnStartService:
        startService(intent);
        break;
    case R.id.btnStopService:
        stopService(intent);
        break;
    case R.id.btnBindService:
        //第二个参数是ServiceConnection接口实现类对象,用this实现,会复写两个方法,第三个参数是一个标记
        bindService(intent, this, Context.BIND_AUTO_CREATE);
        break;
    case R.id.btnUnbindService:
        unbindService(this);
        break;
    }   
}
@Override
//提示绑定成功
public void onServiceConnected(ComponentName name, IBinder binder) {
    System.out.println("MainActivity---onServiceConnected");
}
@Override
//当Service出现异常崩溃的情况时会调用该方法
public void onServiceDisconnected(ComponentName arg0) {
}

但此时点击 绑定Service 按钮不会执行onServiceConnected(),这是因为我们在复写EchoService的onBind()时的默认返回值为null,它的返回值类型为Ibinder,
我们可以通过在Service中建一个内部类,继承自Binder,返回一个这个内部类的对象(可以用final修饰)

    private final EchoServiceBinder echoServiceBinder = new EchoServiceBinder();
    @Override
    public IBinder onBind(Intent arg0) {
        System.out.println("EchoService---onBind");
        return echoServiceBinder;
    }
    //创建Service的Binder内部类
    public class EchoServiceBinder extends Binder{
        //返回EchoService的对象
        public EchoService getService(){
            return EchoService.this;
        }
    }

这样就可以在绑定成功时调用到onServiceConnected().

接下来实现在bindService()的Activity与Service的交互
就只将代码贴出来:

//MainActivity中
public class MainActivity extends ActionBarActivity implements OnClickListener, ServiceConnection{
    Intent intent;
    EchoService echoService = null;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.fragment_main);
        intent = new Intent(this, EchoService.class);
        findViewById(R.id.btnStartService).setOnClickListener(this);
        findViewById(R.id.btnStopService).setOnClickListener(this);
        findViewById(R.id.btnBindService).setOnClickListener(this);
        findViewById(R.id.btnUnbindService).setOnClickListener(this);
        findViewById(R.id.btnGetServiceNum).setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch(v.getId()){
        case R.id.btnStartService:
            startService(intent);
            break;
        case R.id.btnStopService:
            stopService(intent);
            break;
        case R.id.btnBindService:
            bindService(intent, this, Context.BIND_AUTO_CREATE);
            break;
        case R.id.btnUnbindService:
            unbindService(this);
            echoService = null;
            break;
        case R.id.btnGetServiceNum:
            if(echoService != null){
                System.out.println("当前Service中的数字为:"+ echoService.getServiceNum());
            }
            break;
        }

    }

    @Override
    public void onServiceConnected(ComponentName name, IBinder binder) {
        System.out.println("MainActivity---onServiceConnected");
        echoService = ((EchoServiceBinder)binder).getService();
    }

    @Override
    public void onServiceDisconnected(ComponentName arg0) {

    }

}
//在EchoService中
public class EchoService extends Service{

    private final EchoServiceBinder echoServiceBinder = new EchoServiceBinder();
    private int i = 0;
    private Timer timer = null;
    private TimerTask task = null;
    @Override
    public IBinder onBind(Intent arg0) {
        System.out.println("EchoService---onBind");
        return echoServiceBinder;
    }
    @Override
    public void onCreate() {
        super.onCreate();
        System.out.println("EchoService---onCreate");
        //Service启动时启动计时器
        startTimer();
    }
    @Override
    public void onDestroy() {
        super.onDestroy();
        System.out.println("EchoService---onDestory");
        //Service销毁时关闭计时器
        stopTimer();
    }
    //创建Service的Binder内部类
    public class EchoServiceBinder extends Binder{
        //返回EchoService的对象
        public EchoService getService(){
            return EchoService.this;
        }
    }
    //返回Service中当前的i的值
    public int getServiceNum(){
        return i;
    }
    //启动计时器
    private void startTimer(){
        if(timer == null){
            timer = new Timer();
            task = new TimerTask() {

                @Override
                public void run() {
                    i++;
                    System.out.println(i);
                }
            };
            timer.schedule(task, 1000, 1000);
        }
    }
    //关闭计时器
    private void stopTimer(){
        timer.cancel();
    }

}
点击查看更多内容
2人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
移动开发工程师
手记
粉丝
24
获赞与收藏
198

关注作者,订阅最新文章

阅读免费教程

感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消