【0196】Android 性能优化--Service优化
1.基本知识
service:后台服务,专门用来处理常驻后台的工作的组件
即时通讯:service来做常驻后台的心跳传输。
使用服务注意点:核心服务尽可能地轻!!!如果服务的任务量过重,则容易出现bug。
很多人喜欢把所有的后台操作都集中在一个service里面,这是不好的习惯。应该为核心服务专门做一个进程,跟其他的所有后台操作隔离。
2.进程的优先级
进程的重要性优先级:(越往后的就越容易被系统杀死)
1.前台进程;Foreground process
- 1)用户正在交互的Activity(onResume())
- 2)当某个Service绑定正在交互的Activity。
- 3)被主动调用为前台Service(startForeground())
- 4)组件正在执行生命周期的回调(onCreate()/onStart()/onDestroy())
- 5)BroadcastReceiver 正在执行onReceive();
2.可见进程;Visible process
- 1)我们的Activity处在onPause()(没有进入onStop())
- 2)绑定到前台Activity的Service。
3.服务进程;Service process
- 简单的startService()启动。
4.后台进程;Background process
- 对用户没有直接影响的进程----Activity出于onStop()的时候。
android:process=":xxx"
5.空进程; Empty process
- 不含有任何的活动的组件。(android设计的,为了第二次启动更快,采取的一个权衡)
3.建立一像素锁屏保留进程
qq使用一像素Activity,在锁屏的启动该一像素acitivity,被锁屏界面覆盖在下面。当屏幕解锁的时候自动杀死该Activity,得到保留该app的进程不被杀死。
需要配合Service,
【KeepLiveActivity.java】保留一个像素的Acitivity
1 public class KeepLiveActivity extends Activity { 2 3 private static final String TAG = "ricky"; 4 5 @Override 6 protected void onCreate(Bundle savedInstanceState) { 7 super.onCreate(savedInstanceState); 8 // setContentView(R.layout.activity_main); 9 Log.i(TAG, "KeepLiveActivity----onCreate!!!"); 10 11 Window window = getWindow(); 12 window.setGravity(Gravity.LEFT|Gravity.TOP); 13 LayoutParams params = window.getAttributes(); 14 params.height = 1; 15 params.width = 1; 16 params.x = 0; 17 params.y = 0; 18 19 window.setAttributes(params); 20 21 KeepLiveActivityManager.getInstance(this).setKeepLiveActivity(this); 22 } 23 24 @Override 25 protected void onDestroy() { 26 // TODO Auto-generated method stub 27 super.onDestroy(); 28 Log.i(TAG, "KeepLiveActivity----onDestroy!!!"); 29 } 30 31 }
【ScreenListener】锁屏监听,系统在锁屏/解锁屏幕的时候会发出广播,listener用于监听广播,通过接口将监听的状态回传给Service
1 public class ScreenListener { 2 private Context mContext; 3 private ScreenBroadcastReceiver mScreenReceiver; 4 private ScreenStateListener mScreenStateListener; 5 6 public ScreenListener(Context context) { 7 mContext = context; 8 mScreenReceiver = new ScreenBroadcastReceiver(); 9 } 10 11 /** 12 * screen状态广播接收者 13 */ 14 private class ScreenBroadcastReceiver extends BroadcastReceiver { 15 private String action = null; 16 @Override 17 public void onReceive(Context context, Intent intent) { 18 action = intent.getAction(); 19 if (Intent.ACTION_SCREEN_ON.equals(action)) { // 开屏 20 mScreenStateListener.onScreenOn(); 21 } else if (Intent.ACTION_SCREEN_OFF.equals(action)) { // 锁屏 22 mScreenStateListener.onScreenOff(); 23 } else if (Intent.ACTION_USER_PRESENT.equals(action)) { // 解锁 24 mScreenStateListener.onUserPresent(); 25 } 26 } 27 } 28 29 /** 30 * 开始监听screen状态 31 * 32 * @param listener 33 */ 34 public void begin(ScreenStateListener listener) { 35 mScreenStateListener = listener; 36 registerListener(); 37 getScreenState(); 38 } 39 40 /** 41 * 获取screen状态 42 */ 43 private void getScreenState() { 44 PowerManager manager = (PowerManager) mContext 45 .getSystemService(Context.POWER_SERVICE); 46 if (manager.isScreenOn()) { 47 if (mScreenStateListener != null) { 48 mScreenStateListener.onScreenOn(); 49 } 50 } else { 51 if (mScreenStateListener != null) { 52 mScreenStateListener.onScreenOff(); 53 } 54 } 55 } 56 57 /** 58 * 停止screen状态监听 59 */ 60 public void unregisterListener() { 61 mContext.unregisterReceiver(mScreenReceiver); 62 } 63 64 /** 65 * 启动screen状态广播接收器 66 */ 67 private void registerListener() { 68 IntentFilter filter = new IntentFilter(); 69 filter.addAction(Intent.ACTION_SCREEN_ON); 70 filter.addAction(Intent.ACTION_SCREEN_OFF); 71 filter.addAction(Intent.ACTION_USER_PRESENT); 72 mContext.registerReceiver(mScreenReceiver, filter); 73 } 74 75 public interface ScreenStateListener {// 返回给调用者屏幕状态信息 76 public void onScreenOn(); 77 78 public void onScreenOff(); 79 80 public void onUserPresent(); 81 } 82 }
【Service】使用服务运行在后台,对屏幕的响应进行动作的响应,其中使用了KeepLiveActivityManager
1 public class ScreenService extends Service { 2 3 @Override 4 public IBinder onBind(Intent intent) { 5 return null; 6 } 7 8 @Override 9 public void onCreate() { 10 super.onCreate(); 11 ScreenListener listener = new ScreenListener(this); 12 listener.begin(new ScreenStateListener() { 13 14 @Override 15 public void onUserPresent() { 18 } 19 20 @Override 21 public void onScreenOn() { 22 // 开屏---finish这个一个像素的Activity 23 KeepLiveActivityManager.getInstance(ScreenService.this).finishKeepLiveActivity(); 24 } 25 26 @Override 27 public void onScreenOff() { 28 // 锁屏---启动一个像素的Activity 29 // startActivity(intent); 30 KeepLiveActivityManager.getInstance(ScreenService.this).startKeepLiveActivity(); 31 } 32 }); 34 } 36 }
【KeepLiveActivityManager.工具类】主要对一像素Acitivity的begin和finish
1 public class KeepLiveActivityManager { 2 private static KeepLiveActivityManager instance; 3 private Context context; 4 private WeakReference<Activity> activityInstance; 5 6 public static KeepLiveActivityManager getInstance(Context context) { 7 if(instance==null){ 8 instance = new KeepLiveActivityManager(context.getApplicationContext()); 9 } 10 return instance; 11 } 12 13 private KeepLiveActivityManager(Context context) { 14 this.context = context; 15 } 16 17 public void setKeepLiveActivity(Activity activity){ 18 activityInstance = new WeakReference<Activity>(activity); 19 } 20 21 public void startKeepLiveActivity() { 22 Intent intent = new Intent(context, KeepLiveActivity.class); 23 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 24 context.startActivity(intent); 25 } 26 public void finishKeepLiveActivity() { 27 if(activityInstance!=null&&activityInstance.get()!=null){ 28 Activity activity = activityInstance.get(); 29 activity.finish(); 30 } 31 } 32 33 }
【MainAcitivity】 开启服务,点击按钮之后跳转到一像素的Activity
1 public class MainActivity extends Activity { 2 3 @Override 4 protected void onCreate(Bundle savedInstanceState) { 5 super.onCreate(savedInstanceState); 6 setContentView(R.layout.activity_main); 7 8 Intent intent = new Intent(this, ScreenService.class); 9 startService(intent); 10 } 11 12 public void jump(View v){ 13 Intent intent = new Intent(this, KeepLiveActivity.class); 14 startActivity(intent); 15 finish(); 16 } 17 }
在跳转之后可以操作锁屏键,看到一像素Activity的运行,在锁屏时,KeepLiveActivity 的onCreate方法会被调用,在解锁屏幕的时候,KeepLiveActivity 的onDestory方法会被调用。说明该进程确实被锁屏时保留了。
3.双进程守护
一像素Activity能够正常工作的前提是Service的能够在后台保留,如果系统将Service杀死(通过手机设置中对进程的管理同样可以杀死进程),则通过一像素Activity保留app进程会失效,因此使用双进程守护。
浙公网安备 33010602011771号