【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进程会失效,因此使用双进程守护。

 

posted @ 2018-08-05 16:36  OzTaking  阅读(621)  评论(0)    收藏  举报