
方法介绍:
- onCreate():服务第一次被创建时调用
- onStartComand():服务启动时调用
- onBind():服务被绑定时调用
- onUnBind():服务被解绑时调用
- onDestroy():服务停止时调用
Service介绍:
- Service不依赖用户界面,就算启动服务的组件被销毁也不受影响
- 当进程被杀死,所以依赖该进程的Service也会停止运行
- Service只有一个实例,也就是说onCreate方法只会调用一次
- 一个Service必须要在既没有和任何Activity关联又处理停止状态的时候才会被销毁
Service有三种形式
1、启动
调用startService(),启动服务生命周期如上图左侧:onCreate()、onStartCommand(),可以多次调用startService,当调用时实例已存在,不会再次调用onCreate而是直接调用onStartCommand(),无论调用多少次startService(),只需调用一次stopService()或stopSelf()方法,服务就会停止了。
2、绑定
- 调用bindService(),启动服务生命周期如上图左侧:onCreate()、onBind()。再次调用bindService()不会再回调onCreate()、onBind()方法,调用unBindService(),会回调onUnBind()->onDestroy()。
3、绑定且启动
可以即绑定又启动服务,但实例最会有一个。注意的是需要同时调用 stopService()和 unbindService()方法才能让服务销毁掉。
1、后台服务
Service实现程序后台运行,默认在主线程,所以不适合做耗时操作,除非在Service中创建子线程来完成耗时工作。
实例:
清单文件声明:
<service
android:name=".service.MyService"
android:enabled="true"
android:exported="false"/>
Service
package com.example.lenovo.mpplication.service;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import com.example.lenovo.mpplication.R;
public class MyService extends Service {
private static final String TAG = MyService.class.getSimpleName();
public MyService() {
}
@Override
public void onCreate() {
super.onCreate();
Log.e(TAG, "onCreate");
}
//每startService一次,startId++
@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");
}
@Override
public IBinder onBind(Intent intent) {
Log.e(TAG, "onBind");
return null;
}
}
开启服务
Intent startIntent = new Intent(this, MyService.class);
startService(startIntent);
停止服务
Intent stopIntent = new Intent(this, MyService.class);
stopService(stopIntent);
2、前台服务
Service几乎是后台服务,优先级低,当系统出现内存不足情况下,可以会回收正在后台执行的Service。如果希望Service可以一直保持运行状态,可以考虑使用前台Service。会出现通知栏显示。
使用场景:墨迹天气
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle("标题标题标题")
.setContentText("内容内容内容内容内容内容");
startForeground(1, mBuilder.build());
3、绑定服务(Service和Activity通信)
如果希望Activity指定让Service去执行任务,那么就要用到绑定服务和解绑服务,重写Service中的onBind方法,返回IBinder对象。Activity获取IBinder对象,可以通过该接口开始与服务进行交互。
实例:
Service
package com.example.lenovo.mpplication.service;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import com.example.lenovo.mpplication.R;
public class MyService extends Service {
private static final String TAG = MyService.class.getSimpleName();
private MyBinder mBinder = new MyBinder();
public MyService() {
}
@Override
public void onCreate() {
super.onCreate();
Log.e(TAG, "onCreate");
}
@Override
public void onDestroy() {
super.onDestroy();
Log.e(TAG, "onDestroy");
}
@Override
public IBinder onBind(Intent intent) {
Log.e(TAG, "onBind");
return mBinder;
}
public static class MyBinder extends Binder {
public void startDownload() {
Log.e(TAG, "startDownload() executed");
// 执行具体的下载任务
}
}
}
Activity与Service建立联系
private MyService.MyBinder myBinder;
private ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
myBinder = (MyService.MyBinder) service;
myBinder.startDownload();
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
//绑定Service
Intent bindIntent = new Intent(this, MyService.class);
bindService(bindIntent, connection, BIND_AUTO_CREATE);
//解绑Service
unbindService(connection);
ServiceConnection的onServiceConnected方法是指服务连接时,我们可以拿到Service的onBind返回的Binder,调用Binder相关方法,控制Service执行任务。
onServiceDisconnected是服务断开连接时调用
IntentService
package com.example.lenovo.mpplication.service;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import com.example.lenovo.mpplication.R;
public class MyService extends Service {
private static final String TAG = MyService.class.getSimpleName();
private MyBinder mBinder = new MyBinder();
public MyService() {
}
@Override
public void onCreate() {
super.onCreate();
Log.e(TAG, "onCreate");
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle("这是标题吧~叶应是叶")
.setContentText("http://blog.csdn.net/new_one_object");
startForeground(1, mBuilder.build());
}
@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");
}
@Override
public IBinder onBind(Intent intent) {
Log.e(TAG, "onBind");
return mBinder;
}
public static class MyBinder extends Binder {
public void startDownload() {
Log.e(TAG, "startDownload() executed");
// 执行具体的下载任务
}
}
}
3、IntentService
- Service是所有服务的基类,默认情况下在主线程运行。
- IntentService是其子类,使用子线程来处理所有的启动请求,一次一个。无法同时处理多个请求。
- 实现onHandlerIntent(),并在该函数中完成耗时操作即可。在任务执行完毕后IntentService会调用stopSelf()自我销毁
- 适合执行短期耗时任务
实例:
定义IntentService
package com.example.lenovo.mpplication.service;
import android.app.IntentService;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
public class MyIntentService extends IntentService {
private final String TAG = "MyIntentService";
public MyIntentService() {
super("MyIntentService");
}
@Override
protected void onHandleIntent(Intent intent) {
Log.e(TAG, "onHandleIntent Thread----"+Thread.currentThread().getName());
for (int i = 0; i < 5; i++) {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
启动IntentService
Intent intent = new Intent(this, MyIntentService.class);
Bundle bundle = new Bundle();
bundle.putString("key", "当前值:" + 0);
intent.putExtras(bundle);
startService(intent);
4、android:exported
android:exported="true" 是允许别的应用访问
安卓5以上无法通过隐式启动Service
可以使用setClassName(包名, 类的全名)调用其他进程的Service。
例如
Intent intent = new Intent();
intent.setClassName("com.example.lenovo.mpplication","com.example.lenovo.mpplication.components.service.MyIntentService");
intent.putExtra("AAA",3);
startService(intent);
网友评论