1. 程式人生 > >如何檢測Activity是否存活

如何檢測Activity是否存活

     專案中遇到一個問題,在視訊通話時,有時候頁面會異常崩潰,對於Activity是不會走正常的生命週期的,我們的程式必須知道這個Activity是否存在,這期間用了幾種方式去實現這個點,結果都不是很好,最終決定使用定時器去做這塊:


1.使用一個服務不斷檢測目標activity是否存在。好了問題來了,這種方式比較消耗資源,主要是你的service一直執行在後臺,在配置比較差的android裝置上表現不是很好。這個想法直接否定。

2.我自己的想法是使用定時器;在activity啟動時,隨之在一個已經存在的service中啟動一個定時器,這個定時器主要內容是不斷檢測這個activity是否存在,這中間涉及到3個要點:

  • 目標activity在配置檔案中的啟動方式標註為android:launchMode="singleInstance",也就是這個activity單獨開一個Task。這點是為了方便檢查,同時還有業務上的考慮
  • 由於我們已經存在一個常駐後臺的服務,所以在這裡就不需要重啟一個service,只需要在這個服務中啟動一個定時器去輪詢檢測activity記錄,就可以做到這點了
  • 最後一點是,定時器獨有的屬性。就是每個定時器以及任務只能執行一次。再次需要Task時,需要重新new一個物件。

說了這些,下面貼上我的程式碼

<span style="font-size:18px;">        private final static int DEFAULT_TIME = 3500;
        private ConcurrentHashMap<String,Task> guardMap = new ConcurrentHashMap<String, Task>();
        
        class Task extends TimerTask implements Closeable{
                
                private final String CLASSNAME = "需要檢查的類名,需要帶上包名";
                private final int DEFAULT_NUM = 4;
                
                private String id;
                private Timer timer;
                
                private ActivityManager am;
                // 任務是否關閉
                private boolean isClose = false;

                public Task(String _id){
                        this.id = _id;
                }
                
                @Override
                public void run() {
                        if(!checkActivityStatus()){
                                try {
                                        if(!isClose){
                                               // 做一些activity相關變數的維護,標示這個activity是否存在

                                                XXApplication.getPreference().setKeyValue(PrefType.PHONE_CALL_RUNNING, "false");

                                                TvConnectedActivity.isDialService = false;        
                                                
                                                this.close();
                                        }
                                } catch (Exception e) {
                                        LogUtil.d(e.getLocalizedMessage());
                                }
                        }
                }
                
                private boolean checkActivityStatus(){
                        boolean mark = false;
                        String className;
                        if(am == null){am = (ActivityManager)BizServices.this.getSystemService(ACTIVITY_SERVICE);}
                    List<RunningTaskInfo> appTask = am.getRunningTasks(DEFAULT_NUM);

                     if (appTask.size() > 0){
                            for(RunningTaskInfo info :appTask){
                                    className = info.topActivity.getClassName();
                                    if(CLASSNAME.equals(className)){
                                            if(info.numRunning > 0){
                                                    mark = true;
                                            }
                                            return mark;
                                    }
                            }
                     }
                     return mark;
                }

                public void setTimer(Timer timer) {
                        this.timer = timer;
                }
                
                @Override
                public void close() throws IOException {
                        
                        if(isClose){
                                // 關閉一次
                                return;
                        }
                        
                        isClose = true;
                        this.cancel();
                        
                        if(timer != null){
                                timer.cancel();
                                timer.purge();
                        }
                        if(guardMap.containsKey(id)){
                                guardMap.remove(id);
                        }
                }
        };
        
        private void startInspectorMonitor(boolean isStart) {
                if (isStart) {
                        
                        try {
                                Thread.sleep(DEFAULT_TIME+500);
                        } catch (Exception e) {
                        }
                        
                        if(guardMap.size() > 0){
                                return;
                        }else{
                                openTask();
                        }
                } else {
                        
                        Collection<Task> list = guardMap.values();
                        
                        if(guardMap.size() > 0){
                                for(Task task :list){
                                        try {
                                                task.close();                
                                        } catch (Exception e) {
                                        }
                                }
                        }
                        // 做一些activity相關變數的維護,標示這個activity是否存在
                        NetPhoneApplication.getPreference().setKeyValue(PrefType.PHONE_CALL_RUNNING, "false");

                }
        }
        
        private void openTask() {
                Timer timer = new Timer();
                
                String key = CommonUtil.getUUID();
                Task task = new Task(key);
                task.setTimer(timer);
                
                timer.schedule(task, DEFAULT_TIME, DEFAULT_TIME);
                guardMap.put(key, task);
        }</span>