Service
生命周期方法具体介绍
主要介绍内部调用方法和外部调用方法的关系。
1.1 startService()
- 作用:启动Service服务
- 手动调用startService()后,自动调用内部方法:onCreate()、onStartCommand()
- 调用逻辑如下:
1.2 stopService()
- 作用:关闭Service服务
- 手动调用stopService()后,自动调用内部方法:onDestory()
- 调用的逻辑
1.3 bindService()
- 作用:绑定Service服务
- 手动调用bindService()后,自动调用内部方法:onCreate()、onBind()
- 调用的逻辑:
1.4 unbindService()
- 作用:解绑Service服务
- 手动调用unbindService()后,自动调用内部方法:onCreate()、onBind()、onDestory()
- 调用的逻辑:
2. 常见的生命周期使用
2.1 只使用startService启动服务的生命周期
2.2 只使用BindService绑定服务的生命周期
2.3 同时使用startService()启动服务、BindService()绑定服务的生命周期
- 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;
}
}
-
- 创建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;
}
};
}
- Service(服务)是一个可以在后台执行长时间运行操作而没有用户界面的应用组件。
服务进程通信是采用Binder方式,进程间通信,我们可以采用Bundle,文件,ContentProvider,Messenger,AIDL,Socket方式,但是Bundle传输的对象必须实现序列化,所以有些Bundle不支持的类型我们无法通过Bundle传输。采用文件共享方式,linux系统支持并发读写,所以在多个进程间采用文件进行通信并不可靠,而ContentProvider,Messenger和AIDL底层都是采用Binder方式实现的,采用Socket网络方式进行进程间通信,消耗资源大,而且UI线程不支持网络通信。
- 注意事项
- 同一个Activity或者不同Activity,startService多次,除第一次调用onCreate()、onStartCommand外,其余只会调用onStartCommand().
- 只要有一个Activity调用stopService(),服务就会调用onDestroy()停止。
- 同一个Activity或者不同Actvity,bindService多次,只会第一次调用一次onCreate()、onBind().
- 需要所有绑定的Activty调用unBindService()或者Activity关闭(自动解绑),服务才会调用onDestroy()停止。