如何檢測Activity是否存活
阿新 • • 發佈:2019-02-07
專案中遇到一個問題,在視訊通話時,有時候頁面會異常崩潰,對於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>