安卓核心技术中级——Service

四个方法:

onStartCommand()

The system calls this method when another component, such as an activity, requests that the service be started, by calling startService(). Once this method executes, the service is started and can run in the background indefinitely. If you implement this, it is your responsibility to stop the service when its work is done, by calling stopSelf() or stopService(). (If you only want to provide binding, you don't need to implement this method.)

onStartCommand()的返回值

START_STICKY:如果service进程被kill掉,保留service的状态为开始状态,但不保留递送的intent对象。随后系统会尝试重新创建service,由 于服务状态为开始状态,所以创建服务后一定会调用onStartCommand(Intent,int,int)方法。如果在此期间没有任何启动命令被传 递到service,那么参数Intent将为null。

START_NOT_STICKY:“非粘性的”。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统不会自动重启该服务

START_REDELIVER_INTENT:重传Intent。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统会自动重启该服务,并将Intent的值传入。

START_STICKY_COMPATIBILITY:START_STICKY的兼容版本,但不保证服务被kill后一定能重启。

onBind()

The system calls this method when another component wants to bind with the service (such as to perform RPC), by calling bindService(). In your implementation of this method, you must provide an interface that clients use to communicate with the service, by returning an IBinder. You must always implement this method, but if you don't want to allow binding, then you should return null.

onCreate()

The system calls this method when the service is first created, to perform one-time setup procedures (before it calls either onStartCommand() or onBind()). If the service is already running, this method is not called.

onDestroy()

The system calls this method when the service is no longer used and is being destroyed. Your service should implement this to clean up any resources such as threads, registered listeners, receivers, etc. This is the last call the service receives.

 

两种方式

StartService

Service

1.服务同时只会被创建一次,可以通过外部调用stopService或者通过调用stopSelf终止服务
2.当执行一个已启动的服务,会直接调用onStartCommand方法来执行业务
3.默认情况下,服务与主线程在一个进程中的同一个线程中执行,如果服务执行一个比较耗时的操作,我们必须使用子线程来完成工作 避免阻塞主线程
4.使用start service启动的一个服务,在没有关闭之前会一直在后台运行

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

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }

    @Override
    public void onCreate() {
        super.onCreate();
        System.out.println("my service create.");
    }

    //在该方法中实现服务的核心业务
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        System.out.println(intent.getStringExtra("info"));
        //使用线程完成长时间的工作
        new Thread(new Runnable() {
            @Override
            public void run() {
                for(int i=0;i<50;i++){
                    System.out.println("onStartCommand"+i+"-"+Thread.currentThread().getName());
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                    if(i == 30){
                        MyService.this.stopSelf();//终止
                        break;
                    }
                }
            }
        }).start();

        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        System.out.println("my service destroyed");
    }
}


//MainActivity.java
//启动一个服务
    public void startClick(View v){
        Intent intent = new Intent(this,MyService.class);
        intent.putExtra("info","大家不要再买票");
        startService(intent);
    }

    //停止一个服务
    public void stopClick(View v){
        Intent intent = new Intent(this,MyService.class);
        stopService(intent);
    }

IntentService

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=0;i<50;i++){
            System.out.println("onHandleIntent-"+i+"-"+Thread.currentThread().getName());
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

}

//MainActivity.java
//启动一个服务
    public void startIntentClick(View v){
        Intent intent = new Intent(this,MyIntentService.class);
        intent.putExtra("info","我要坐砖机回家过年");
        startService(intent);
    }

BoundService

应用程序组件(客户端)通过调用bindService()方法个绑定服务,然后Android系统会调用服务的onBind()回调方法,这个方法回访一个跟服务的交互的IBinder对象。这个绑定是异步的,bindService()方法立即返回,并且不给客户端返回IBinder对象。要接收IBinder对象,客户端必须创建一个ServiceConnection实例,并且把这个实例传递给bindService()方法。
ServiceConnection对象包含了一个系统调用的传递IBinder对象的回调方法。
注意:只有Activity,Service,和内容提供器(content provider)能绑定服务——对于广播接收器不能绑定服务。

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

1.客户端通过bindService方法来绑定一个服务对象,如果绑定成功,回调onServiceConnected

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

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

    一个aidl文件
          (1)不能有修饰符,类似接口的写法
          (2)支持类型有:8中基本数据类型,String,CharSequence,List<String>,Map,自定义类型

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

5.通过Service的onBind方法返回被绑定的业务对象

6.客户端如果绑定成功,就可以像调用自己的方法一样调用原创的业务对象

android:process=":remote"设置运行的进程

//MyBoundService.java


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();
    }
}
//CatImpl.java
public class CatImpl extends ICat.Stub {

    private String name;

    public void setName(String name) throws RemoteException{
        this.name = name;
    }

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

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

    }

}
//ICat.aidl
interface ICat {

    void setName(String name);
    String desc();

    /**
     * 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);
}
//MainActivity.java
//绑定服务的连接回调接口
    private ServiceConnection conn = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            //绑定成功后回调的方法
            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 callClick(View v){
        if(cat == null){
            return;
        }
        try {
            cat.setName("喵喵");
            Toast.makeText(this,cat.desc(),Toast.LENGTH_LONG).show();
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

    //绑定一个服务
    public void boundClick(View v){
        Intent intent = new Intent(this,MyBoundService.class);
        //异步绑定,绑定成功后会回调onServiceConnected
        bindService(intent,conn, Context.BIND_AUTO_CREATE);
    }

    //解除绑定
    public void unBoundClick(View v){
        if(mBound){
            unbindService(conn);
            Toast.makeText(MainActivity.this,"解除绑定",Toast.LENGTH_SHORT).show();
        }
    }

猜你喜欢

转载自blog.csdn.net/asjklm/article/details/88976109