Android Service的绑定和非绑定服务

时间:2024-04-09 08:13:03

Service介绍:

Service是系统四大组件之一,它的后台运行并不是子线程,Service的运行是在主线程中进行的,只是它没有界面显示而已,它的耗时操作同样需要开启子线程,否者会跟Activity一样出现ANR。它不能在页面显示,只能在后台运行,可以与其他组件进行交互。Service的用途很广,比如播放多媒体的时候用户启动了其他Activity这个时候程序要在后台继续播放,比如检测SD卡上文件的变化,再或者在后台记录你地理信息位置的改变等等,官方给出Service的优先级挺高的,当内存不足的时候,保证Service尽量不被系统杀死。

下面是两种服务的生命周期:

Android Service的绑定和非绑定服务

绑定服务:

被绑定的service是当其他组件(一个客户)调用bindService()来创建的。客户可以通过一个IBinder接口和service进行通信。客户可以通过 unbindService()方法来关闭这种连接。一个service可以同时和多个客户绑定,当多个客户都解除绑定之后,系统会销毁service。

下面是运行结果:

Android Service的绑定和非绑定服务

首先是下了两个按钮,点击的时候会在log打印出现,一个是点击绑定,一个是点击解绑

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity" >

    <Button
        android:id="@+id/mBtn1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="BindService"
        />
    <Button
        android:id="@+id/mBtn2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="UNbindService"
        />
</LinearLayout>
写服务,必须要写一个类,然后继承自Service,同时别忘了在配置清单里面注册,如果一个Service在某个Activity中被调用bindService方法启动,不论bindService被调用几次,Service的onCreate方法只会执行一次,当建立连接后,Service会一直运行,除非调用unbindService来接触绑定、断开连接或调用该Service的Context不存在了(如Activity被Finish——即通过bindService启动的Service的生命周期依附于启动它的Context),系统在这时会自动停止该Service。

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;

public class BindService extends Service{
    private String tag="BindService";
    @Override
    public void onCreate() {
        // TODO Auto-generated method stub
        super.onCreate();
        Log.e(tag, "onCreate");
    }
    @Override
    public IBinder onBind(Intent intent) {
        Log.e(tag, "onBind");
        return new MyBind();
    }
    @Override
    public boolean onUnbind(Intent intent) {
        // TODO Auto-generated method stub
        Log.e(tag, "onUnbind");
        return super.onUnbind(intent);

    }
    @Override
    public void onDestroy() {
        // TODO Auto-generated method stub
        super.onDestroy();
        Log.e(tag, "onDestroy");
    }

    public void getLast(){
        Log.e("", "下一曲");
    }

    public class MyBind extends Binder{
        public BindService getservice(){
            return BindService.this;
        }
    }
}

实现绑定服务监听,必须实现ServiceConnection接口

import android.os.Bundle;
import android.os.IBinder;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class MainActivity extends Activity implements OnClickListener {
    private Button mBtn1,mBtn2;
    private Conn conn;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        conn=new Conn();
        initView();
    }
    private void initView() {
        mBtn1=(Button) findViewById(R.id.mBtn1);
        mBtn2=(Button) findViewById(R.id.mBtn2);

        mBtn1.setOnClickListener(this);
        mBtn2.setOnClickListener(this);
    }
    @Override
    public void onClick(View v) {
        if(R.id.mBtn1==v.getId()){
            //绑定服务
            Intent intent=new Intent(MainActivity.this, BindService.class);
            bindService(intent, conn, Context.BIND_AUTO_CREATE);
        }else{
            //服务解绑
            unbindService(conn);
        }
    }
    //绑定服务监听
    private class Conn implements ServiceConnection{
        //绑定服务成功的监听  service:是服务绑定成功后的返回值:onbund方法的返回值
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            BindService.MyBind bind=(BindService.MyBind) service;
            bind.getservice().getLast();
        }
        //因为异常,绑定服务失败的监听
        @Override
        public void onServiceDisconnected(ComponentName name) {
            // TODO Auto-generated method stub
        }
    }
}

非绑定服务

从图中可以看出,启动一次之后,onCreate方法已经不走了,直接走onStartCommand方法

Android Service的绑定和非绑定服务

只有停止服务之后,才会重新走创建这个方法

Android Service的绑定和非绑定服务

下面为非绑定服务代码,继承自Service,然后实现了非绑定服务的生命周期,onBind()方法是系统实现的,在这里不做任何操作。

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.util.Log;

public class MyService extends Service{
    @Override
    public void onCreate() {
        Log.e("MyService","onCreate");
        super.onCreate();
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.e("MyService","onStartCommand");
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        Log.e("MyService","onDestroy");
        super.onDestroy();
    }
}
在这里我在布局写了两个按钮,

第一个按钮是启动服务,

第二个按钮是退出的时候调用的stopService();关闭服务

import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class MainActivity extends Activity implements OnClickListener {
    private Button mBtn1,mBtn2;
    Intent intent;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
    }
    private void initView() {
        mBtn1=(Button) findViewById(R.id.mBtn1);//启动服务
        mBtn2=(Button) findViewById(R.id.mBtn2);
        mBtn1.setOnClickListener(this);
        mBtn2.setOnClickListener(this);
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
    }

    @Override
    public void onClick(View v) {

        switch (v.getId()){
            case R.id.mBtn1:
               intent=new Intent(MainActivity.this,MyService.class);
                startService(intent);
                break;
            case R.id.mBtn2:
                intent=new Intent(MainActivity.this,MyService.class);
                stopService(intent);//在退出的时候关闭Service
                break;
        }
    }
}