天天看点

Android四大组件之ServiceService

Service

基本概念

Service是Android系统中的四大组件之一, 它跟Activity的级别差不多, 但不能自己运行只能后台运行, 并且可以和其他组件进行交互。Service可以在很多场合的应用中使用,比如播放多媒体的时候用户启动了其他Activity这个时候程序要在后台继续播放,比如检测SD卡上文件的变化,再或者在后台记录你地理信息位置的改变等等,总之服务总是藏在后台的。

Service的生命周期

Android四大组件之ServiceService

onStartComand的返回参数

Android四大组件之ServiceService

启动和停止一个Service

//启动一个服务
 Intent intent = new Intent(this, MyService.class);
        startService(intent);
//停止一个服务
Intent intent = new Intent(this, MyService.class);
        stopService(intent);
           

Note:

started service:

1, 服务同时只会被创建一次,可以通过外部调用stopServic或者调用stopSelf终止自己的服务

2, 当执行一个以启动的服务,会直接调用onStartCommand方法来执行业务

3, 默认情况下服务与主线程同一个进程中的同一个线程中执行,如果执行一个比较耗时的操作,我们必须使用子线程完成工作, 避免主线程被阻塞

4, 使用started Service启动的一个服务在没有关闭之前会一直在后台运行!

IntentService

Android四大组件之ServiceService

Note:

1, 内部有一个工作线程完成耗时操作, 只需要实现onHandleIntent()方法即可

2,完成工作后停止服务

3,同时执行多个任务时,会以工作队列的方式依次执行

4, 通常使用该类完成本App的耗时工作

public class MyIntentService extends IntentService {

    public MyIntentService() {
        super("MyIntentService");
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        System.out.println(intent.getStringExtra("info"));
        for (int i = ; i < ; i++) {
            System.out.println("onHandleIntent " + i + " " + Thread.currentThread().getName());
            try {
                Thread.sleep();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }
}
           

Bind Service

Android四大组件之ServiceService

Note:

绑定服务:

通过绑定服务来实现功能的步骤:

1, 客户端通过bindService方法来绑定一个服务对象, 如果绑定成功, 会回调ServiceConnection接口中的onServiceConnected

2, 通过Service组件来暴露业务接口

3, 服务端通过创建一个*.aidl文件, 来定义一个可以被客户端调用的业务接口

一个aidl文件:

  (1) 不能有修饰符, 类似接口的写法

  (2) 支持的类型有8种基本数据类型和 String CharSequence, List, Map, 自定义类型

自定义类型要实现Parcelable接口

定义一个aidl文件声明该类型

在其他aidl文件中使用, 必须要使用import

4, 服务端需要提供一个业务接口的实现类, 通常会extends Stub类

5, 通过Service的onBind方法返回被绑定的方法

6, 客户端如果绑定chenggong,就可以像调用自己的方法一样调用远程的业务对象方法

使用技巧

started启动的服务会长期存在, 只要不停

bind启动的服务通常会在解锁时停止

通常情况下, 先started, 后bind

服务端代码

package com.lulu.admin.lservice;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;

public class MyBoundService extends Service {
    public MyBoundService() {
    }

    @Override
    public void onCreate() {
        super.onCreate();
    }

    //绑定
    @Override
    public IBinder onBind(Intent intent) {

        return new CatImpl();

}


    //解除绑定
    @Override
    public boolean onUnbind(Intent intent) {
        return super.onUnbind(intent);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();

     }
}
           

客户端代码

MainActivity.java

private ICat cat;
 private boolean mBound = false;//是否绑定
           
//绑定服务的连接回调接口
    private ServiceConnection conn = new ServiceConnection() {
        //绑定成功后返回的方法
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            //得到cat对象
            cat = ICat.Stub.asInterface(service);
            mBound = true;
            Toast.makeText(MainActivity.this, "绑定成功", Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            //服务异常时调用, 很少使用
            mBound = false;
        }
    };

    //绑定一个服务
    public void boundClick(View view) {
        Intent intent = new Intent(this, MyBoundService.class);
        //异步绑定, 立即返回!
        //绑定成功后会回调onServiceConnected!!!!!!
        bindService(intent, conn, Context.BIND_AUTO_CREATE);  //如果没有创建就自动创建,如果创建了就不用了
    }

    //解绑的方法
    public void unBoundClick(View view) {
        if (mBound) {
            unbindService(conn);
            Toast.makeText(MainActivity.this, "解绑成功", Toast.LENGTH_SHORT).show();
            mBound = false;
        }
    }

    //
    public void callClick(View v) {
        if (cat == null) {
            return;
        }

        try {
            cat.setName("喵猫");

            Toast.makeText(MainActivity.this, cat.desc() + " " + cat.getPerson().toString(), Toast.LENGTH_SHORT).show();

        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }
           

Person.java

package com.lulu.admin.lservice;

import android.os.Parcel;
import android.os.Parcelable;

/**
 * Created by Admin on 2016/5/18.
 */
public class Person implements Parcelable{
    String name;
    String works;

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", works='" + works + '\'' +
                '}';
    }

    public static final Parcelable.Creator<Person> CREATOR
            = new Parcelable.Creator<Person>() {
        public Person createFromParcel(Parcel in) {
            Person p = new Person();
            p.name = in.readString();
            p.works = in.readString();
            return p;
        }
        public Person[] newArray(int size) {
            return new Person[size];
        }
    };



    @Override
    public int describeContents() {
        return ;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(name);
        dest.writeString(works);
    }
}
           

CatImp.java

package com.lulu.admin.lservice;

import android.os.RemoteException;

/**
 * 业务接口的具体实现类
 * Created by Admin on 2016/5/18.
 * Stub是IBind的子类或者说是实现
 */
public class CatImpl extends ICat.Stub {
    private String name;
    @Override
    public void setName(String name) throws RemoteException {
        this.name = name;
    }

    @Override
    public String desc() throws RemoteException {
        return "hello my is" + name + ", I am a Cat";
    }

    @Override
    public Person getPerson() throws RemoteException {
        Person p = new Person();
        p.name = "小次郎";
        p.works = "强盗";
        return p;
    }

    @Override
    public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {

    }
}
           

AIDL文件

ICat.aidl

// ICat.aidl
package com.lulu.admin.lservice;
import com.lulu.admin.lservice.Person;
// Declare any non-default types here with import statements

interface ICat {
    void setName(String name);
    String desc();
    Person getPerson();//获取当前猫的主任
    /**
     * Demonstrates some basic types that you can use as parameters
     * and return values in AIDL.
     */
    void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
            double aDouble, String aString);
}
           

Person.aidl

// Person.aidl
package com.lulu.admin.lservice;

parcelable Person;
           

Messenger

Android四大组件之ServiceService
让我们来大致说一下创建步骤

服务端

1, 首先创建一个handler,需要Service处理的代码在这里处理

2, 创建一个Messenger对象, 传入handler

3, 在onBind方法中返回由Messenger得到的Binder对象

public class MessengerService extends Service {
    public static final int SAY_HELLO = ;

    public MessengerService() {

    }

    @Override
    public IBinder onBind(Intent intent) {
        return messenger.getBinder();
    }

    Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);

            switch (msg.what) {
                case SAY_HELLO:
                    String info = (String) msg.obj;
                    Toast.makeText(getApplicationContext(), info, Toast.LENGTH_SHORT).show();
                    break;
            }

        }
    };
    private Messenger messenger = new Messenger(handler);
}
           

客户端

我引用了API文档中的注释, 过程跟跟前面的讲述的绑定服务差不多
//首先声明一个Messenger
    private Messenger mService = null;
    private boolean mBound2 = false;

    @Override
    protected void onStart() {
        super.onStart();
        //绑定Messenger服务
        bindService(new Intent(this, MessengerService.class), conn2, Context.BIND_AUTO_CREATE);

    }

    @Override
    protected void onStop() {
        super.onStop();
        if(mBound2){
            unbindService(conn2);
            mBound2 = false;
            Toast.makeText(MainActivity.this, "解绑成功", Toast.LENGTH_SHORT).show();
        }
    }

    //使用Messenger方法, 绑定服务的连接回调接口
    private ServiceConnection conn2 = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            // This is called when the connection with the service has been
            // established, giving us the object we can use to
            // interact with the service.  We are communicating with the
            // service using a Messenger, so here we get a client-side
            // representation of that from the raw IBinder object.
            //创建一个Messenger对象传入IBinder的对象
            mService = new Messenger(service);
            mBound2 = true;
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            // This is called when the connection with the service has been
            // unexpectedly disconnected -- that is, its process crashed.
            mService = null;
            mBound2 = false;
        }
    };
    //使用Messenger方法
    public void messengerClick(View v) {
        if(!mBound2){
            return;
        }
        // Create and send a message to the service, using a supported 'what' value
        Message msg = Message.obtain();
        msg.what = MessengerService.SAY_HELLO;
        msg.obj = "你好啊";
        try {
            mService.send(msg);
        } catch (RemoteException e) {
            e.printStackTrace();
        }

    }
           

Demo下载地址: http://download.csdn.net/download/u013144863/9524589

以上纯属个人见解, 如有不足之处希望有高人指出, 定感激不尽, 如有喜欢交流学习经验请给我留言谢谢.