Launcher中Shortcut的创建流程简析
本文将以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的使命。