本文將以Contacts的Direct dial為例,來解析在Launcher創建shortcut的流程
Direct dial在AndroidManifest.xml(Contacts)中聲明如下:
<activity-alias android:name="alias.DialShortcut" android:targetActivity=".activities.ContactSelectionActivity" android:label="@string/shortcutDialContact" android:icon="@mipmap/ic_launcher_shortcut_directdial" android:enabled="@*android:bool/config_voice_capable"> <intent-filter> <action android:name="android.intent.action.CREATE_SHORTCUT" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.CAR_MODE" /> </intent-filter> </activity-alias>
這樣,在Launcher的WIDGETS頁面便可找到Direct dial(android.intent.action.CREATE_SHORTCUT)。
我們將Direct dial拖拽到桌面后,會觸發.activities.ContactSelectionActivity.選擇一個聯系人,就完成了Direct dial的創建。
點擊該shortcut將跳轉到給我們選擇的聯系人打電話界面。
下面是我打的Log,重要步驟都被標紅了。
-----------在launcher widget頁面選擇direct dial(shortcut)並拖拽到launcher主界面-----------
DragController-->onTouchEvent()-->MotionEvent.ACTION_UP, try to do drop()
DragController-->drop()
Workspace-->onDrop()
Workspace-->onDropExternal()
Launcher-->processShortcutFromDrop()-->componentName: com.android.contacts/alias.DialShortcut
Launcher-->resetAddInfo()
Launcher-->processShortcut()
Launcher-->startActivityForResultSafely()-->requestCode : 1
DragLayer-->clearAnimatedView()
ContactSelectionActivity-->onCreate()--start
ContactSelectionActivity-->onCreate()-->mActionCode : -1
ContactSelectionActivity-->configureListFragment()-->mActionCOde : 120
ContactSelectionActivity-->onCreate()--end
Launcher-->updateRunning()
--------------------------為新建的direct dial快捷方式選擇一個聯系人--------------------------
PhoneNumberPickerFragment-->onItemClick()-->position : 0, id : 1
PhoneNumberPickerFragment-->pickPhoneNumber()-->uri : content://com.android.contacts/data/1
ShortcutIntentBuilder-->createPhoneNumberShortcutIntent()-->uri : content://com.android.contacts/data/1, shortcutAction : android.intent.action.CALL
ShortcutIntentBuilder-->PhoneNumberLoadingAsyncTask-->loadData()-->mDisplayName : gaojx, mPhotoId : 0, mPhoneNumber : 155 2487, mPhoneType : 2, mPhoneLabel : null
ShortcutIntentBuilder-->PhoneNumberLoadingAsyncTask-->onPostExecute()
ShortcutIntentBuilder-->createPhoneNumberShortcutIntent()
PhoneNumberPickerFragment-->onShortcutIntentCreated()
ContactSelectionActivity-->PhoneNumberPickerActionListener-->onShortcutIntentCreated()
ContactSelectionActivity-->returnPickerResult()
Launcher-->onActivityResult()-->requestCode : 1, resultCode : -1
Launcher-->onActivityResult()-->resultCode == RESULT_OK && mPendingAddInfo.container != ItemInfo.NO_ID
Launcher-->completeAdd()-->args.requestCode : 1
Launcher-->completeAddShortcut()-->container : -100, screen : 2, cellX : 1, cellY : 2
Launcher-->createShortcut()-->start
BubleTextView-->applyFromShortcutInfo()-->info.title : gaojx
Launcher-->createShortcut()-->end
Workspace-->createUserFolderIfNecessary()
Workspace-->addToExistingFolderIfNecessary()
LauncherModel-->addItemToDatabase()
Workspace-->addInScreen()
Launcher-->resetAddInfo()
DragLayer-->clearAnimatedView()
Launcher-->exitSpringLoadedDragModeDelayed()-->successfulDrop : true
Launcher-->updateRunning()
Launcher-->showWorkspace()
Launcher-->showWorkspace()-->mState != State.WORKSPACE
Launcher-->updateRunning()
----------------------------點擊launcher主界面上新建的direct dial--------------------------------
Launcher-->onClick()
Launcher-->onClick()-->tag instanceof ShortcutInfo
Launcher-->startActivitySafely()
Launcher-->startActivity()-->Action => android.intent.action.CALL, Data => tel:155%202487
OutgoingCallBroadcaster-->onCreate()
OutgoingCallBroadcaster-->processIntent()-->intent=Intent { act=android.intent.action.CALL dat=tel:xxxxxxxxxxxxx flg=0x14800000 cmp=com.android.phone/.OutgoingCallBroadcaster bnds=[120,387][240,543] }
Launcher-->updateRunning()
....................................................................................................
通過上面的Log我們可以看出shortcut的流程是:
一:聲明時指定的targetActivity屬性是Launcher創建shortcut時要使用的。即Launcher的startActivityForResultSafely將啟動我們設定的targetActivity,讓我們選擇該shortcut對應的聯系人。
二:選擇完聯系人后將調用Launcher的onActivityResult()來真正完成shortcut的創建工作。
三:點擊shortcut時將調用Launcher的onClick函數處理點擊事件,最終通過Launcher的startActivitySafely函數調用startActivity函數(參數intent是我們從onActivityResult()得到的)完成該shortcut的使命。