参考自:http://blog.csdn.net/guolin_blog/article/details/11952435
http://blog.csdn.net/javazejian/article/details/52709857
一,Service的基本用法:
1,创建一个Service:MyService extends Service,并重写onCreate(), onStartCommand()和onDestroy()
-------------- onStart() 已经不使用。
2,启动和停止Service:
Intent startIntent = new Intent(this, MyService.class);
startService(startIntent);
3, 需要在AndroidManifest中生命该Service
<service
android:name=".MyService"
android:enabled="true"
android:exported="true"></service>
二,Service 和 Activity通信:Service的绑定:onBind() bindService();
1) 增加新类MyBinder类继承自Binder类:
class MyBinder extends Binder {
public void startDownload() {
Log.d(TAG, "startDownload() executed");
}
}
2) 并在onBind()时返回该MyBinder实例:
private MyBinder mBinder = new MyBinder();
@Override
public IBinder onBind(Intent intent) {
Log.d("MyService", "====== onBind ============");
return mBinder;
}
3) 定义ServiceConnection: 用于在Activity和Service之间连接上之后的处理动作:connection
private MyService.MyBinder myBinder;
private ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder service) {
myBinder = (MyService.MyBinder) service;
myBinder.startDownload();
Log.d("ServiceConnection", " ======== onServiceConnected ============ ");
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
Log.d("ServiceConnection", " ======== onServiceDisConnected ============ ");
}
};
4) 在Activity中绑定该ServiceConnection:
Intent bindIntent = new Intent(this, MyService.class);
bindService(bindIntent, connection, BIND_AUTO_CREATE);
通过上述动作,就可以把Activity和Service绑定,并把任务交到Service去处理。
参考,标准的Service实现模型:
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
new Thread(new Runnable() {
@Override
public void run() {
// 开始执行后台任务
}
}).start();
return super.onStartCommand(intent, flags, startId);
}
class MyBinder extends Binder {
public void startDownload() {
new Thread(new Runnable() {
@Override
public void run() {
// 执行具体的下载任务
}
}).start();
}
}
三,Service的生命周期:
startService() 和 BindService() 均可以启动一个Service,两者的生命周期如下:
需要注意的是Service的销毁,当同时使用StartService()和bindService() 一起调用Service的,如果Service还被绑定,直接调用StopService()是无法销毁该Service的
四,创建前台Service:
创建前台Service的目的:1,提高后台运行Service的优先级;2,避免系统因内存不足而kill掉该Service。
前台Service和普通Service的最大的区别在于:它会一直有一个正在运行的图标显示在状态栏。
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
notificationIntent, 0);
Notification.Builder builder = new Notification.Builder(this)
.setContentIntent(pendingIntent)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("这是通知的标题");
Notification notification = builder.build();
startForeground(1, notification); //调到前台
五,Android 5.0以上的隐式启动问题:
在Android 5.0之后google出于安全的角度禁止了隐式声明Intent来启动Service。
解决办法:
* 设置Action和packageName:
final Intent serviceIntent=new Intent(); serviceIntent.setAction("com.android.ForegroundService");
serviceIntent.setPackage(getPackageName());//设置应用的包名
startService(serviceIntent);
public static Intent getExplicitIntent(Context context, Intent implicitIntent) {
// Retrieve all services that can match the given intent
PackageManager pm = context.getPackageManager();
List<ResolveInfo> resolveInfo = pm.queryIntentServices(implicitIntent, 0);
// Make sure only one match was found
if (resolveInfo == null || resolveInfo.size() != 1) {
return null;
}
// Get component info and create ComponentName
ResolveInfo serviceInfo = resolveInfo.get(0);
String packageName = serviceInfo.serviceInfo.packageName;
String className = serviceInfo.serviceInfo.name;
ComponentName component = new ComponentName(packageName, className);
// Create a new intent. Use the old one for extras and such reuse
Intent explicitIntent = new Intent(implicitIntent);
// Set the component to be explicit
explicitIntent.setComponent(component);
return explicitIntent;
}
Intent mIntent=new Intent();//辅助Intent
mIntent.setAction("com.android.ForegroundService");
final Intent serviceIntent=new Intent(getExplicitIntent(this,mIntent));
startService(serviceIntent);
问题,如果Service在AndroidManifest中设置process属性,调用startService或者BindService;其中onCreate(), onStartCommand() 不会被调用。
需要通过调用AIDL相应的接口,实现所需要的远程调用。
六,