Service

生命周期方法具体介绍

主要介绍内部调用方法和外部调用方法的关系。

1.1 startService()

  • 作用:启动Service服务
  • 手动调用startService()后,自动调用内部方法:onCreate()、onStartCommand()
  • 调用逻辑如下: 

Service

1.2 stopService()

  • 作用:关闭Service服务
  • 手动调用stopService()后,自动调用内部方法:onDestory()
  • 调用的逻辑

Service

1.3 bindService()

  • 作用:绑定Service服务
  • 手动调用bindService()后,自动调用内部方法:onCreate()、onBind()
  • 调用的逻辑:

Service

1.4 unbindService()

  • 作用:解绑Service服务
  • 手动调用unbindService()后,自动调用内部方法:onCreate()、onBind()、onDestory()
  • 调用的逻辑: 

Service

 

2. 常见的生命周期使用

2.1 只使用startService启动服务的生命周期

Service

2.2 只使用BindService绑定服务的生命周期

Service

2.3 同时使用startService()启动服务、BindService()绑定服务的生命周期

Service

  1. Service的创建

 

  • 创建Started Service
  • 继承IntentService

public class MyIntentService extends IntentService {

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

    @Override
    protected void onHandleIntent(@Nullable Intent intent) {
        int msg = intent.getIntExtra("msg",0);
        int count=0;
        while (true){
            Log.i("androidLog","msg.what="+msg+";count="+count);
            count++;
            if(count>100){
                break;
            }
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

 

  • 继承Service类

public class MyService extends Service {

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

    class ServiceHandler extends Handler{

        int count =0;
        public ServiceHandler(Looper looper){
            super(looper);
        }

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            while (true){
                Log.i("androidLog","msg.what="+msg.what+";count="+count);
                count++;
                if(count>100){
                    break;
                }
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            stopSelf();
        }

    }

    @Override
    public void onCreate() {
        super.onCreate();
    }
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        int msg = intent.getIntExtra("msg",0);
        HandlerThread thread = new HandlerThread(""+msg, Process.THREAD_PRIORITY_BACKGROUND);
        thread.start();
        serviceHandler = new ServiceHandler(thread.getLooper());
        serviceHandler.sendEmptyMessageAtTime(msg,1000);
        return START_STICKY;
    }
}

 

 

    1. 创建Bound Service

一、继承Binder类(进程内通信)

public class MyBoundService extends Service {

    LocalBinder localBinder;
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        localBinder = new LocalBinder();
        return localBinder;
    }

    public class LocalBinder extends Binder{
        MyBoundService getService(){
            return MyBoundService.this;
        }
    }

    public int getRandomNumber(){
        return new Random().nextInt(10);
    }
}

 

二、使用Messenger类

 

public class MainActivity extends AppCompatActivity {

    boolean bound=false;
    Intent intent;
    Messenger messengerSend;
    Messenger messengerRecv;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        intent = new Intent(this,CustomBindService2.class);
        bindService(intent,sc,Context.BIND_AUTO_CREATE);
    }

    Handler handler = new Handler(){

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            Log.e("androidLog","what="+msg.what);
        }
    };

    public void btnClick(View view) {
        switch (view.getId()){
            case R.id.btnStart:
                Message msg = new Message();
                msg.what=100;
                messengerRecv = new Messenger(handler);
                msg.replyTo=messengerRecv;
                try {
                    messengerSend.send(msg);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
                break;
            case R.id.btnStop:
                stopService(intent);
                break;
        }
    }

    ServiceConnection sc= new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            messengerSend = new Messenger(service);
            bound = true;
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            bound = false;
        }
    };
}

 

 

public class CustomBindService2 extends Service {

    Messenger messengerRev;
    Messenger messengerReply;

    public CustomBindService2() {
        messengerRev = new Messenger(handler);
    }

    Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            Log.e("androidLog","what="+msg.what);
            messengerReply = msg.replyTo;
            Message message = new Message();
            message.what=50;
            try {
                messengerReply.send(message);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
    };

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

 

 

三、使用AIDL(接口定义语言)来创建绑定服务

  • 使用Android studio生成AIDL文件

// IMyAidlInterface.aidl
package hyh.com.servicedemo;
import hyh.com.servicedemo.Person;//这个必须要

interface IMyAidlInterface {

    void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
            double aDouble, String aString);

    int sum(int a,int b);

    void printPerson(in Person person);

}

 

  • 创建Person对象,并且使用Parcelable序列化

public class Person implements Parcelable  {

    public int id;
    public String name;

    protected Person(Parcel in) {
        id = in.readInt();
        name = in.readString();
    }

    public Person(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public static final Creator<Person> CREATOR = new Creator<Person>() {
        @Override
        public Person createFromParcel(Parcel in) {
            return new Person(in);
        }

        @Override
        public Person[] newArray(int size) {
            return new Person[size];
        }
    };

    @Override
    public int describeContents() {
        return 0;
    }

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

 

  • 创建Person的AIDL文件,注意名字要和类名相同,且在同一个包内

// Person.aidl
package hyh.com.servicedemo;
parcelable Person;

 

  • 服务端

public class CustomBindService3 extends Service {
  

    @Override
    public IBinder onBind(Intent intent) {
        return new IMyAidlInterfaceImpl();
    }

     class IMyAidlInterfaceImpl extends IMyAidlInterface.Stub {

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

         }

         @Override
        public int sum(int a, int b) throws RemoteException {
            return a+b;
        }

         @Override
         public void printPerson(Person person) throws RemoteException {
             Log.e("androidLog",person.name+":"+person.id);
         }
     }
}

 

  • 客户端

public class MainActivity extends AppCompatActivity {

    boolean bound=false;
    Intent intent;
    IMyAidlInterface iMyAidlInterface;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        intent = new Intent(this,CustomBindService3.class);
        bindService(intent,sc,Context.BIND_AUTO_CREATE);
    }

    public void btnClick(View view) {
        switch (view.getId()){
            case R.id.btnStart:
                try {
                    Log.e("androidLog","sum="+iMyAidlInterface.sum(1,2));
                    Person person = new Person(10,"hyh");
                    iMyAidlInterface.printPerson(person);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
                break;
            case R.id.btnStop:
                break;
        }
    }

    ServiceConnection sc= new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            iMyAidlInterface = IMyAidlInterface.Stub.asInterface(service);
            bound = true;
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            bound = false;
        }
    };
}

 

  1. Service(服务)是一个可以在后台执行长时间运行操作而没有用户界面的应用组件。

服务进程通信是采用Binder方式,进程间通信,我们可以采用Bundle,文件,ContentProvider,Messenger,AIDL,Socket方式,但是Bundle传输的对象必须实现序列化,所以有些Bundle不支持的类型我们无法通过Bundle传输。采用文件共享方式,linux系统支持并发读写,所以在多个进程间采用文件进行通信并不可靠,而ContentProvider,Messenger和AIDL底层都是采用Binder方式实现的,采用Socket网络方式进行进程间通信,消耗资源大,而且UI线程不支持网络通信。

 

  1. 注意事项
  • 同一个Activity或者不同Activity,startService多次,除第一次调用onCreate()、onStartCommand外,其余只会调用onStartCommand().
  • 只要有一个Activity调用stopService(),服务就会调用onDestroy()停止。
  • 同一个Activity或者不同Actvity,bindService多次,只会第一次调用一次onCreate()、onBind().
  • 需要所有绑定的Activty调用unBindService()或者Activity关闭(自动解绑),服务才会调用onDestroy()停止。