Activity啟動模式

處理啟動模式的方法的是StackAcivity的代理類StackActivitySupervisor里的startActivityUncheckedLocked.
前面主要是根據(jù)Flag來判斷需不需要addTask.
當New_Task_Flag時风钻, 且instask, resultTo為null, 除了single instance都會去taskHistory去找ActivityRecord散怖。singleInstance 例子最后再說。當找到時就會嘗試著將r (這次要啟動的activity)放進去,或者resumeTask里的Activity仅父。
這里講解下ActivityStack里的找ActivityRecord的findTaskLocked方法:

task.rootAffinity.equals(target.taskAffinity)
  • 默認情況下赠群,一個應用中的所有activity具有相同的taskAffinity羊始,即應用程序的包名。所以這里用affinity作為判斷條件來判別是否為想要的
taskIntent.getComponent().compareTo(cls)==0 && Objects.equals(documentData,taskDocumentData)
  • 第二個匹配下 component(調用java compareTo 0為true)查描, document若為null返回為true
affinityIntent.getComponent().compareTo(cls) ==0&&Objects.equals(documentData,taskDocumentData)
  • 最后為affinityIntent的component突委。

當找到相對應的的record,且curTop不為找到record的task。這時用targetstack的moveTaskToFrontLocked. 在這些條件下addingtoTask為false &&reuseTask ==null 會做doResume操作冬三。

  • 當 lauchflag 為clearTop或者singleInstance或者singleTask匀油,且能在task找到歷史的activityrecord。
 if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0   || launchSingleInstance || launchSingleTask) {   
 // In this situation we want to remove all activities 
 // from the task up to the one being started.  In most 
 // cases this means we are resetting the task to its    
// initial state.    
 ActivityRecord top =  intentActivity.task.performClearTaskLocked(r, launchFlags);  
   if (top != null) {       
    if (top.frontOfTask) {            
// Activity aliases may mean we use different            
// intents for the top activity, so make sure            
// the task now has the identity of the new            
// intent.           
     top.task.setIntent(r);       
 }       
 ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT,  r, top.task);     
 top.deliverNewIntentLocked(callingUid, r.intent);    
}

這里提一下FLAG_ACTIVITY_CLEAR_TOP這個方法勾笆。 當intent被標記上這個,會去task找相對應的ActivityRecord敌蚜,找到后會清空其上的Activity然后做Resume(singleInstance和SignleTask也是如此)

  • 當要啟動的acitivty的reactivity ( //the intent component, or target of an alias.) 跟task的realActivity相等時( task的realActivity為root)。 且 與task的root intent相等窝爪。
if(r.realActivity.equals(intentActivity.task.realActivity)
   if (!r.intent.filterEquals(intentActivity.task.intent)) {    
// In this case we are launching the root activity    
// of the task, but with a different intent.  We    
// should start a new instance on top.    
   addingToTask = true;   
   sourceRecord = intentActivity
}
  • 上面兩個沒匹配到, 且lauchFlags 不為reset_task
    (launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0

如果說沒有做onRume操作, 后面會判斷是否需要new一個新task弛车,條件如下

if (r.resultTo == null && inTask == null && !addingToTask  && (launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) 
// In this case an activity is being launched in to an
// existing task, without resetting that task.  This
// is typically the situation of launching an activity
// from a notification or shortcut.  We want to place
// the new activity on top of the current task.

若不new task會執(zhí)行

if (sourceRecord != null) {    
  final TaskRecord sourceTask = sourceRecord.task;    
  if (isLockTaskModeViolation(sourceTask)) {        
  Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r);        
  return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;    
  }    
  targetStack = sourceTask.stack;    
  targetStack.moveToFront();    
  final TaskRecord topTask = targetStack.topTask();    
  if (topTask != sourceTask) {            
    targetStack.moveTaskToFrontLocked(sourceTask, r, options);    
  } else {        
    mWindowManager.moveTaskToTop(topTask.taskId);   
}

最后調用targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);


singleTop 只會判斷下頂部activity是否為想調用的如果是就resumeTop

if (top != null && r.resultTo == null) {   
  if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) {            
    if (top.app != null && top.app.thread != null) {           
      if ((launchFlags & Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0 || launchSingleTop || launchSingleTask) {        
                 ...            
                 resumeTopActivitiesLocked();             
                 ...
   }   }  }  }

SingleInstance 比較特殊, 嘗試去找歷史Activity findActivityLocked(intent, r.info);.

/** * Returns the first activity (starting from the top of the stack) that 
* is the same as the given activity.  Returns null if no such activity 
* is found. 
*/
ActivityRecord findActivityLocked(Intent intent, ActivityInfo info) {    ComponentName cls = intent.getComponent();    
if (info.targetActivity != null) {        
cls = new ComponentName(info.packageName, info.targetActivity);    
}    
final int userId = UserHandle.getUserId(info.applicationInfo.uid);    
for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {        TaskRecord task = mTaskHistory.get(taskNdx);       
   if (!isCurrentProfileLocked(task.userId)) {            
        return null;        
    }          
   final ArrayList<ActivityRecord> activities = task.mActivities;        
   for (int activityNdx = activities.size() - 1; 
   activityNdx >= 0; --activityNdx) {            
   ActivityRecord r = activities.get(activityNdx);            
   if (!r.finishing && r.intent.getComponent().equals(cls) && r.userId ==   
    userId) {                
        //Slog.i(TAG, "Found matching class!");                
        //dump();                
        //Slog.i(TAG, "For Intent " + intent + " bringing to top: " + r.intent);                       
        return r;           
       }        
    }    
  }    
  return null;
}

另外當其它的activity嘗試去用它所屬的task時會直接將其過濾掉齐媒。

(r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE ){
if (DEBUG_TASKS) Slog.d(TAG, "Skipping " + task + ": mismatch root " + r);
continue;
}

最后說下Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET)這個flag. 如果intent被標記這個flag, 當task重置時它之上的activity都會被清掉。

if (clearWhenTaskReset) { 
// In this case, we want to finish this activity 
// and everything above it, so be sneaky and pretend
// like these are all in the reply chain.
end = numActivities - 1;
}
最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末纷跛,一起剝皮案震驚了整個濱河市喻括,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌贫奠,老刑警劉巖唬血,帶你破解...
    沈念sama閱讀 212,454評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異唤崭,居然都是意外死亡拷恨,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評論 3 385
  • 文/潘曉璐 我一進店門谢肾,熙熙樓的掌柜王于貴愁眉苦臉地迎上來腕侄,“玉大人,你說我怎么就攤上這事勒叠《蛋ぃ” “怎么了膏孟?”我有些...
    開封第一講書人閱讀 157,921評論 0 348
  • 文/不壞的土叔 我叫張陵眯分,是天一觀的道長。 經(jīng)常有香客問我柒桑,道長弊决,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,648評論 1 284
  • 正文 為了忘掉前任魁淳,我火速辦了婚禮飘诗,結果婚禮上,老公的妹妹穿的比我還像新娘界逛。我一直安慰自己昆稿,他們只是感情好,可當我...
    茶點故事閱讀 65,770評論 6 386
  • 文/花漫 我一把揭開白布息拜。 她就那樣靜靜地躺著溉潭,像睡著了一般。 火紅的嫁衣襯著肌膚如雪少欺。 梳的紋絲不亂的頭發(fā)上喳瓣,一...
    開封第一講書人閱讀 49,950評論 1 291
  • 那天,我揣著相機與錄音赞别,去河邊找鬼畏陕。 笑死,一個胖子當著我的面吹牛仿滔,可吹牛的內(nèi)容都是我干的惠毁。 我是一名探鬼主播犹芹,決...
    沈念sama閱讀 39,090評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼鞠绰!你這毒婦竟也來了羽莺?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,817評論 0 268
  • 序言:老撾萬榮一對情侶失蹤洞豁,失蹤者是張志新(化名)和其女友劉穎盐固,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體丈挟,經(jīng)...
    沈念sama閱讀 44,275評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡刁卜,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,592評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了曙咽。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蛔趴。...
    茶點故事閱讀 38,724評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖例朱,靈堂內(nèi)的尸體忽然破棺而出孝情,到底是詐尸還是另有隱情,我是刑警寧澤洒嗤,帶...
    沈念sama閱讀 34,409評論 4 333
  • 正文 年R本政府宣布箫荡,位于F島的核電站,受9級特大地震影響渔隶,放射性物質發(fā)生泄漏羔挡。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 40,052評論 3 316
  • 文/蒙蒙 一间唉、第九天 我趴在偏房一處隱蔽的房頂上張望绞灼。 院中可真熱鬧,春花似錦呈野、人聲如沸低矮。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,815評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽军掂。三九已至,卻和暖如春姆打,著一層夾襖步出監(jiān)牢的瞬間良姆,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,043評論 1 266
  • 我被黑心中介騙來泰國打工幔戏, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留玛追,地道東北人。 一個月前我還...
    沈念sama閱讀 46,503評論 2 361
  • 正文 我出身青樓,卻偏偏與公主長得像痊剖,于是被迫代替她去往敵國和親韩玩。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,627評論 2 350

推薦閱讀更多精彩內(nèi)容