老婆保佑优俘,代碼無BUG
前言
項目中遇到一個需求京办,需要竟可能的上傳用戶的定位信息,引發(fā)了我對目前已知的狈溃活手段的探究惭婿,同時也遇到過客戶說,推送不能收到视搏,不能像微信那樣审孽,MMP的,不想理客戶
目錄
- 一:如何創(chuàng)建前臺服務(wù)
- 1.DeskService 前臺服務(wù)
- 2.移除前臺Service通知欄標(biāo)志
- 3.注冊服務(wù)
- 4.啟動服務(wù)
- 二:查看adj級別
一:如何創(chuàng)建前臺服務(wù)
1.DeskService 前臺服務(wù)
package com.cpsc.livedemo;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.Service;
import android.content.Intent;
import android.os.Build;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.util.Log;
/**
* 描述:
* <p>
* Created by allens on 2018/1/31.
*/
public class DeskService extends Service {
private static final String TAG = "DaemonService";
public static final int NOTICE_ID = 100;
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "DaemonService---->onCreate被調(diào)用浑娜,啟動前臺service");
//如果API大于18佑力,需要彈出一個可見通知
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
Notification.Builder builder = new Notification.Builder(this);
builder.setSmallIcon(R.mipmap.ic_launcher);
builder.setContentTitle("KeepAppAlive");
builder.setContentText("DaemonService is runing...");
startForeground(NOTICE_ID, builder.build());
// 如果覺得常駐通知欄體驗不好
// 可以通過啟動CancelNoticeService,將通知移除筋遭,oom_adj值不變
Intent intent = new Intent(this, CancelNoticeService.class);
startService(intent);
} else {
startForeground(NOTICE_ID, new Notification());
}
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// 如果Service被終止
// 當(dāng)資源允許情況下打颤,重啟service
return START_STICKY;
}
@Override
public void onDestroy() {
super.onDestroy();
// 如果Service被殺死暴拄,干掉通知
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
NotificationManager mManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
mManager.cancel(NOTICE_ID);
}
Log.d(TAG, "DaemonService---->onDestroy,前臺service被殺死");
// 重啟自己
Intent intent = new Intent(getApplicationContext(), DeskService.class);
startService(intent);
}
}
2.移除前臺Service通知欄標(biāo)志
package com.cpsc.livedemo;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.Service;
import android.content.Intent;
import android.os.Build;
import android.os.IBinder;
import android.os.SystemClock;
import android.support.annotation.Nullable;
/**
* 描述:
* <p>
* Created by allens on 2018/1/31.
*/
public class CancelNoticeService extends Service {
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN_MR2) {
Notification.Builder builder = new Notification.Builder(this);
builder.setSmallIcon(R.mipmap.ic_launcher);
startForeground(DeskService.NOTICE_ID, builder.build());
// 開啟一條線程编饺,去移除DaemonService彈出的通知
new Thread(new Runnable() {
@Override
public void run() {
// 延遲1s
SystemClock.sleep(1000);
// 取消CancelNoticeService的前臺
stopForeground(true);
// 移除DaemonService彈出的通知
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
manager.cancel(DeskService.NOTICE_ID);
// 任務(wù)完成乖篷,終止自己
stopSelf();
}
}).start();
}
return super.onStartCommand(intent, flags, startId);
}
}
3.注冊服務(wù)
<service
android:name=".DeskService"
android:enabled="true"
android:exported="true"
android:process=":daemon_service" />
<service
android:name=".CancelNoticeService"
android:enabled="true"
android:exported="true"
android:process=":service" />
4.啟動服務(wù)
startService(new Intent(this, DeskService.class));
二:查看adj級別
adb shell
ps|grep <package_name>
查看基本信息
1|root@generic_x86:/ # ps|grep com.cpsc.livedemo
u0_a63 6834 1348 1285208 43884 SyS_epoll_ b73712b5 S com.cpsc.livedemo
u0_a63 6884 1348 1271160 28944 SyS_epoll_ b73712b5 S com.cpsc.livedemo:daemon_service
值 | 解釋 |
---|---|
u0_a63 | USER 進程當(dāng)前用戶 |
6834 | 進程ID |
1348 | 進程的父進程ID |
1285208 | 進程的虛擬內(nèi)存大小 |
43884 | 實際駐留”在內(nèi)存中”的內(nèi)存大小 |
com.cpsc.livedemo | 進程名 |
cat /proc/<進程id>/oom_adj
root@generic_x86:/ # cat /proc/6884/oom_adj
1
root@generic_x86:/ # cat /proc/6884/oom_adj
1
root@generic_x86:/ #
adj級別 | 值 | 說明 |
---|---|---|
UNKNOWN_ADJ | 16 | 預(yù)留的最低級別,一般對于緩存的進程才有可能設(shè)置成這個級別 |
CACHED_APP_MAX_ADJ | 15 | 緩存進程透且,空進程撕蔼,在內(nèi)存不足的情況下就會優(yōu)先被kill |
CACHED_APP_MIN_ADJ | 9 | 緩存進程,也就是空進程 |
SERVICE_B_ADJ | 8 | 不活躍的進程 |
PREVIOUS_APP_ADJ | 7 | 切換進程 |
HOME_APP_ADJ | 6 | 與Home交互的進程 |
SERVICE_ADJ | 5 | 有Service的進程 |
HEAVY_WEIGHT_APP_ADJ | 4 | 高權(quán)重進程 |
BACKUP_APP_ADJ | 3 | 正在備份的進程 |
PERCEPTIBLE_APP_ADJ | 2 | 可感知的進程秽誊,比如那種播放音樂 |
VISIBLE_APP_ADJ | 1 | 可見進程 |
FOREGROUND_APP_ADJ | 0 | 前臺進程 |
PERSISTENT_SERVICE_ADJ | -11 | 重要進程 |
PERSISTENT_PROC_ADJ | -12 | 核心進程 |
SYSTEM_ADJ | -16 | 系統(tǒng)進程 |
NATIVE_ADJ | -17 | 系統(tǒng)起的Native進程 |