从android O版本开始,google为了控制资源使用增加了两项后台限制:
- 后台服务
- 广播
今天主要说后台服务
其中对于后台服务的限制,指的是如果应用处于后台,则不允许直接使用startService
可以使用新增的startForgroundService api启动前台服务(在调用此api之后5s之内必须调用startFroground启动前台服务通知)
那什么是后台应用?后台的对立面是前台,google对于前台的定义如下:
- 具有可见的activity(不管该activity已启动还是已暂停)
- 具有前台服务
- 有关联的前台应用(如壁纸,通知侦听器等)
具体可参考官方链接:
https://developer.android.com/about/versions/oreo/background
思路:如果app在前台的时候,service一般不会被干掉,切到后台只能存活1分钟左右就会被系统干掉,当service被干掉就会执行onDestory方法,在onDestory中启动一个1像素的activity,这个activity启动之后去重新启动下service,然后finish(不能直接在onDestory中启动service,会报错),这样就能保证service在后台长时间存活
废话不多说,直接上代码:
public class FirstService extends Service {
private final String TAG = "FirstService";
public static void start(Context context){
Intent intent = new Intent(context, FirstService.class);
AndroidOAdapter.startService(context, intent);
}
Handler handler = new Handler();
int count = 0;
Runnable runnable = new Runnable() {
@Override
public void run() {
Log.d(TAG,"FirstService running "+count++);
if (count==10) SecondService.start(FirstService.this);
handler.postDelayed(this, 1000);
}
};
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
Log.d(TAG,"onCreate... ");
handler.post(runnable);
// bindSecondService();
}
// private void bindSecondService() {
// bindService(new Intent(this, SecondService.class), new ServiceConnection() {
// @Override
// public void onServiceConnected(ComponentName name, IBinder service) {
// Log.d(TAG,"onServiceConnected ");
// SecondService secondService = ((SecondService.LocalBinder) service).getService();
//
// AndroidOAdapter.startForeground(secondService);
// AndroidOAdapter.startForeground(FirstService.this);
// secondService.stopForeground(true);
// FirstService.this.unbindService(this);
// }
//
// @Override
// public void onServiceDisconnected(ComponentName name) {
// Log.d(TAG,"onServiceDisconnected ");
// }
// }, Service.BIND_AUTO_CREATE);
// }
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG,"onStartCommand... ");
return START_STICKY;
}
@Override
public void onDestroy() {
Log.d(TAG,"onDestroy....");
handler.removeCallbacks(runnable);
AndroidOAdapter.onServiceDestory(this);
super.onDestroy();
}
}
public class AndroidOServiceHelpActivity extends Activity {
public static String EXTRA_COMPONENT_NAME = "componentName";
public static void start(Context context, ComponentName componentName){
Intent intent = new Intent(context, AndroidOServiceHelpActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra(EXTRA_COMPONENT_NAME, componentName);
context.startActivity(intent);
}
private String tag = this.getClass().getSimpleName();
Handler handler = new Handler();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setOnePixLayout();
Log.d(tag,"onCreate...");
onStartService(getIntent());
}
@Override
protected void onNewIntent(Intent intent) {
onStartService(intent);
}
private void onStartService(Intent intent) {
Log.d(tag,"onStartService...");
if(intent!=null){
ComponentName componentName = intent.getParcelableExtra(EXTRA_COMPONENT_NAME);
if(componentName!=null){
Intent serviceIntent = new Intent();
serviceIntent.setComponent(componentName);
startService(serviceIntent);
finish();
}
}
finish();
}
private void setOnePixLayout() {
//设置1像素
Window window = getWindow();
window.setGravity(Gravity.LEFT | Gravity.TOP);
WindowManager.LayoutParams params = window.getAttributes();
params.x = 0;
params.y = 0;
params.height = 1;
params.width = 1;
window.setAttributes(params);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
|WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH);
}
@Override
protected void onResume() {
super.onResume();
Log.d(tag,"onResume...");
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.d(tag,"onDestroy...");
}
@Override
protected void onPause() {
super.onPause();
Log.d(tag,"onPause...");
}
@Override
protected void onStop() {
super.onStop();
Log.d(tag,"onStop...");
}
// @Override
// public void onBackPressed() {
//
// }
}
public class AndroidOAdapter {
public static void onServiceDestory(Service service){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && BaseApplication.getAppContext().getApplicationInfo().targetSdkVersion >= 26) {
AndroidOServiceHelpActivity.start(service, new ComponentName(service, service.getClass()));
}
}
}
网友评论