1.创建、启动、关闭Service
创建
public class TestService extends Service{
private String tag = "TestService";
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
Log.e(tag,"onCreate");
}
@Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
Log.e(tag,"onStart");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e(tag,"onStartCommand");
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
Log.e(tag,"onDestroy");
}
}
注册:
<service android:name=".TestService">
<intent-filter>
<action android:name="TestService"/>//启动指定action响应
</intent-filter>
</service>
启动、关闭
boolean isStarted = false;
public void jump(View view) {
Intent intent = new Intent();
intent.setPackage("newsjump.hw.com.newsjumptest");//TestService所在的包名
intent.setAction("TestService");
if (!isStarted) {
isStarted = true;
startService(intent);
} else {
isStarted = false;
stopService(intent);
}
}
运行效果
05-11 10:04:13.182 20780-20780/newsjump.hw.com.newsjumptest E/TestService: onCreate
05-11 10:04:13.183 20780-20780/newsjump.hw.com.newsjumptest E/TestService: onStartCommand
05-11 10:04:13.183 20780-20780/newsjump.hw.com.newsjumptest E/TestService: onStart
05-11 10:04:17.946 20780-20780/newsjump.hw.com.newsjumptest E/TestService: onDestroy
05-11 10:04:20.080 20780-20780/newsjump.hw.com.newsjumptest E/TestService: onCreate
05-11 10:04:20.081 20780-20780/newsjump.hw.com.newsjumptest E/TestService: onStartCommand
05-11 10:04:20.081 20780-20780/newsjump.hw.com.newsjumptest E/TestService: onStart
2.绑定Service并进行通信
可以通过binder进行绑定来通信。
创建可以绑定数据的BindService:
public class BindService extends Service{
private String tag = "BindService";
private MyBinder myBinder = new MyBinder();
@Nullable
@Override
public IBinder onBind(Intent intent) {
Log.e(tag,"onBind");
return myBinder;//返回binder进行绑定
}
public class MyBinder extends Binder{
//自定义业务逻辑方法
public int getMyData(){
return 200;
}
}
@Override
public void onCreate() {
super.onCreate();
Log.e(tag,"onCreate");
}
@Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
Log.e(tag,"onStart");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e(tag,"onStartCommand");
return super.onStartCommand(intent, flags, startId);
}
@Override
public boolean onUnbind(Intent intent) {
Log.e(tag,"onUnbind");
return super.onUnbind(intent);
}
@Override
public void onDestroy() {
super.onDestroy();
Log.e(tag,"onDestroy");
}
}
注册:
<service android:name=".BindService">
<intent-filter>
<action android:name="BindService"/>
</intent-filter>
</service>
创建、绑定、取消绑定:
private String tag = "serviceTest";
boolean isStarted = false;
//通过ServiceConnection进行连接
private ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
BindService.MyBinder myBinder = (BindService.MyBinder) iBinder;//获取到绑定可以通信的binder
Log.e(tag, "serviceConnection,my data:" + myBinder.getMyData());
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
Log.e(tag, "onServiceDisconnected");
}
};
public void jump(View view) {
Intent intent = new Intent(this, BindService .class);
if (!isStarted) {
isStarted = true;
//第三个参数:绑定时是否自动创建Service,传0不自动创建,BIND_AUTO_CREATE自动创建
bindService(intent,serviceConnection, Service.BIND_AUTO_CREATE);
} else {
isStarted = false;
unbindService(serviceConnection);
}
}
运行结果:
05-11 10:18:43.010 15458-15458/newsjump.hw.com.newsjumptest E/BindService: onCreate
05-11 10:18:43.010 15458-15458/newsjump.hw.com.newsjumptest E/BindService: onBind
05-11 10:18:43.016 15458-15458/newsjump.hw.com.newsjumptest E/serviceTest: serviceConnection,my data:200
05-11 10:18:46.200 15458-15458/newsjump.hw.com.newsjumptest E/BindService: onUnbind
05-11 10:18:46.200 15458-15458/newsjump.hw.com.newsjumptest E/BindService: onDestroy
3.startService与bindService生命周期:
startService: onCreate——onStartCommond——运行—–onDestroy
bindService: onCreate——onBind—–运行—–onUnBind——onDestroy
4.IntentService的作用与使用
作用:
Service有两个问题,1.不会专门启动一个单独的进程,与应用程序为同个进程。2.不会专门开一个线程,所以做耗时操作需要自己开线程处理。IntentService可以弥补这两个问题。
创建、注册:
public class TestIntentService extends IntentService {
private String tag = "TestIntentService";
public TestIntentService(String name) {
super(name);
}
public TestIntentService() {//这里需要一个默认构造器,否则不能注册
super("TestIntentService");
}
@Override
public void onCreate() {
super.onCreate();
Log.e(tag,"onCreate");
}
@Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
Log.e(tag,"onStart");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e(tag,"onStartCommand");
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
closed = true;
Log.e(tag,"onDestroy");
}
@Override
protected void onHandleIntent(@Nullable Intent intent) {
//这里可以通过Intent来传递数据进来,数据发送出去可以使用广播
Log.e(tag,"onHandleIntent");
}
}
注册:
<service android:name=".TestIntentService">
</service>
启动,注意使用startService进行启动:
public void jump(View view) {
Intent intent = new Intent();
intent.setClass(this,TestIntentService.class);
if (!isStarted) {
isStarted = true;
startService(intent);
} else {
isStarted = false;
stopService(intent);
}
}
点击启动:
05-11 10:50:46.369 12091-12091/newsjump.hw.com.newsjumptest E/TestIntentService: onCreate
05-11 10:50:46.369 12091-12091/newsjump.hw.com.newsjumptest E/TestIntentService: onStartCommand
05-11 10:50:46.369 12091-12091/newsjump.hw.com.newsjumptest E/TestIntentService: onStart
05-11 10:50:46.370 12091-12194/newsjump.hw.com.newsjumptest E/TestIntentService: onHandleIntent
05-11 10:50:46.372 12091-12091/newsjump.hw.com.newsjumptest E/TestIntentService: onDestroy
发现会调用到onDestroy,说明IntentService相当于一个线程,如果执行完成后就自动停止了,如果我在onHandleIntent中执行耗时处理:
boolean closed = false;
@Override
protected void onHandleIntent(@Nullable Intent intent) {
//这里可以通过Intent来传递数据进来
Log.e(tag,"onHandleIntent");
//注意的是,TestIntentService其实也相当于一个线程,如果onHandleIntent执行完成后,自动停止,执行onDestroy
while(!closed){
}
Log.e(tag,"onHandleIntent finish");
}
执行启动:
05-11 10:52:30.322 15178-15178/newsjump.hw.com.newsjumptest E/TestIntentService: onCreate
05-11 10:52:30.323 15178-15178/newsjump.hw.com.newsjumptest E/TestIntentService: onStartCommand
05-11 10:52:30.323 15178-15178/newsjump.hw.com.newsjumptest E/TestIntentService: onStart
05-11 10:52:30.323 15178-15318/newsjump.hw.com.newsjumptest E/TestIntentService: onHandleIntent
执行结束:
05-11 10:52:45.758 15178-15318/newsjump.hw.com.newsjumptest E/TestIntentService: onHandleIntent finish
05-11 10:52:45.758 15178-15178/newsjump.hw.com.newsjumptest E/TestIntentService: onDestroy
所以,可以当成一个线程处理,完成处理,自动结束,也可以主动结束它。
5.AIDL Service 跨进程调用服务
Android中,各个应用程序运行在自己的进程中,可以通过AIDL Service进行跨进程通信。用的其实不多,这个不多说了,具体再了解吧。
6.系统服务
系统提供了很多系统服务
比如WindowManager:
WindowManager windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
比如TelephonyManager:
TelephonyManager windowManager = (TelephonyManager) getSystemService(TELECOM_SERVICE);
7.注意的地方
1.可以多次进行bindService,如果只有一个页面进行了bindService,那么当这个连接unbindService后,Service将自动销毁,依次执行到ondestroy去。也就是说,当所有连接都解除绑定后,服务将自动停止,否则服务将继续存在。如果所有连接解除绑定,重新绑定注册bindService,服务将重新启动,所有数据将进行初始化。
2.ServiceConnection,onServiceDisconnected方法多数是在绑定该服务的进程(多数是应用进程)被杀死后回调,杀死后服务不会主动移除连接,如果绑定的binder还存活,就是说引用还没被回收,当下次服务回调数据时还是会收到 onServiceConnected回调。
3.使服务运行在指定进程中:
<service
android:name=".socket.mains.AppSocketServer"
android:exported="false"//不给外部使用
android:persistent="true"//指定长期运行
android:process="com.hw.socket">//指定在指定进程中
<intent-filter>
<action android:name="ABindService" />
</intent-filter>
</service>
4.如何尽量使服务器长期运行:
1.android:persistent="true"
2.在 onStartCommand中返回START_STICKY ,作用就是在我指定启动或者停止的时候执行启动或者停止,因为在这个模式下。如果服务被杀死,系统会尝试重新创建启动这个服务。START_NOT_STICKY or START_REDELIVER_INTENT 是在发送数据时候才会存活,长时间不发送数据,可能会停止掉,系统不会尝试重新启动这个服务。
3. onCreate(), onStartCommand(), or onDestroy()中添加代码(比如延时死循环),使系统认为是前台进程。
4. 使用 startForeground让服务变为前台进程。