定义服务:
Service是Android提供允许长时间留驻后台的组件,最常见做法轮询操作
- 服务与线程的区别
Thread是线程,程序执行最小单位,分配CPU基本单位
启动停止服务
- onCreate/onDestory 在整个生命周期中只会调用一次
- startService每次服务启动时都会调用,复用Service对象,不会再创建新实例
活动和服务之间进行通信
-当我们想要启动的是一个下载的后台Service,想要知道下载进度后时,这时候需要Activity与Service通信,他们的交流媒介就是OnBind!返回自定义Binder对象
//自定义Service
//实例化自定义Binder类,重写onBind,返回Binder!
//实例化ServiceConnection,重写ServiceConnected,获取Binder对象
public class MyService extends Service{
private DownloadBinder mBinder=new DownloadBinder();
class DownloadBinder extends Binder{
//在DownLoadBinder内部提供开始下载和查看下载进度方法
//在onBind()中返回实例
public void startDownload((){
Log.d("MyService","Download executed");
}
public int getProgress(){
Log.d...
return 0;
}
public IBinder onBind(Intent intent){
return mBinder;
}
}
}
服务的生命周期
- onStartCommand 每次service对象复用时,回调该方法
- IBinder onBind 必须执行方法,返回IBinder对象,app通过该对象与Service进行通信
- onUnbind 解绑
前台服务
- 服务且不会因为内存不够被回收,例如状态栏
public void onCreate(){
super.onCreate();
Notification.Builder notification=new Notification.Builder(this);
locationBuilder.setContentIntent(PendingIntent.getActivity(this,0,new Intent(this,MainAcctivity.class),0));
locationBuilder.setContentTitle("This is Content title");
locationBuilder.setContentText("This is Content text");
locationBuilder.setSmallIcon(R.drawable.small_icon);
locationBuilder.setAutoCancel(false);
startForeground(1,localBuilder.getNotification());
}
IntentServicce
- 直接在服务里处理耗时逻辑,容易出现ANR(Application Not Responding)–这时候就需要多线程了
- 客户端通过startService(Intent)来启动IntentService,任务执行完后会自动停止,可以被启动多次,以工作队列的方式在的onHandleIntent回调方法中执行,每次只会执行一个工作线程
public class MyIntentService extends IntentService{
private final String TAG="HEHE"
//提供无参构造,必须在内部调用父类有参构造
public MyIntentService(){
super("MyIntentService"); //调用父类的有参构造函数
}
//必须重写的核心方法
protected void onHandleThread(Intent intent){
//Intent从Activity发过来,携带识别承诺书,根据参数不同,执行不同任务
String action=intent.getExtras().getString("param");
if(action.equals("s1"))Log.d(TAG,"启动Service");
try{
Thread.sleep(2000);
}catch(InterruptedException e){
e.printStackTrace();
}
}
/*public void onDestory(){
super.onDestoy();
}*/
}
//MainActivity
Intent intent=new Intent("com.example.MyActivity");
Bundle b1=new Bundle();
b1.putSring("param","s1");
it.putExtras(b1);
startService(intent);
//如果启动多次IntentService,每次启动,都会新建一个线程
//当始终只有一个IntentService实例
简单定时后台线程实现
- 每隔一段时间请求一次服务器,确认客户端状态或进行信息更新
//核心代码
public class LongRunningService extends Service {
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
//开辟一条线程,执行具体的逻辑操作:
new Thread(new Runnable() {
@Override
public void run() {
Log.d("BackService", new Date().toString());
}
}).start();
//getSystemService 获得Service
AlarmManager manager = (AlarmManager) getSystemService(ALARM_SERVICE);
//SystemClock 设置定时任务
//定时操作,每隔两秒打印一次
int anHour = 2 * 1000;
long triggerAtTime = SystemClock.elapsedRealtime() + anHour;
Intent i = new Intent(this,AlarmReceiver.class);
PendingIntent pi = PendingIntent.getBroadcast(this, 0, i, 0);
manager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerAtTime, pi);
//ELAPSED_REALTIME_WAKEUP
//在睡眠状态下唤醒系统并执行提示功能,使用相对时间(相对于系统启动开始)
//AlarmManager.RTC_WAKEUP 绝对时间
//AlarmManager.ELAPSED_REALTIME
//睡眠状态下不可用,相对
//AlarmManager.RTC 绝对时间
//开辟事务线程,处理定时逻辑
return super.onStartCommand(intent, flags, startId);
}
}
//定义广播,用于启动service
public class AlarmReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Intent i = new Intent(context,LongRunningService.class);
context.startService(i);
}
}