launchermodel.java_Android--launcher启动过程解析

本文出自:http://blog.csdn.net/lilu_leo/article/details/6988326

第一步:我们先从LauncherApplication.java开始,先找到onCreate()方法:

public voidonCreate() {//设置最小堆内存8M

VMRuntime.getRuntime().setMinimumHeapSize(8 * 1024 * 1024); //llx modify the heapsize

super.onCreate();//建立应用图标缓存器

mIconCache = new IconCache(this);//建立LauncherModel

mModel = new LauncherModel(this, mIconCache);//Register intent receivers//注册Intent.ACTION_PACKAGE_ADDED,Intent.ACTION_PACKAGE_REMOVED,//Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE,//Intent.ACTION_LOCALE_CHANGED 事件监听器//LauncherModel作为广播接收器对上面事件进行监听

IntentFilter filter = newIntentFilter(Intent.ACTION_PACKAGE_ADDED);

filter.addAction(Intent.ACTION_PACKAGE_REMOVED);

filter.addAction(Intent.ACTION_PACKAGE_CHANGED);

filter.addDataScheme("package");

registerReceiver(mModel, filter);

filter= newIntentFilter();

filter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);

filter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);

registerReceiver(mModel, filter);

filter= newIntentFilter();

filter.addAction(Intent.ACTION_LOCALE_CHANGED);

registerReceiver(mModel, filter);//Register for changes to the favorites//添加对桌面favorites content provider 数据变化监听器

ContentResolver resolver =getContentResolver();

resolver.registerContentObserver(LauncherSettings.Favorites.CONTENT_URI,true,mFavoritesObserver);

}

第二步:看下Launcher.java中的onCreate()方法:

protected voidonCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);//获取LauncherApplication LauncherModel mIconCache等LauncherApplication初始化的对象

LauncherApplication app =((LauncherApplication)getApplication());

mModel= app.setLauncher(this);

mIconCache=app.getIconCache();//新建拖放控制器new DragController(this)

mDragController = new DragController(this);

mInflater=getLayoutInflater();//获取桌面组件管理器,启动桌面组件host

mAppWidgetManager = AppWidgetManager.getInstance(this);

mAppWidgetHost= new LauncherAppWidgetHost(this, APPWIDGET_HOST_ID);

mAppWidgetHost.startListening();if(PROFILE_STARTUP) {

android.os.Debug.startMethodTracing("/sdcard/launcher");

}//从array.hotseats中加载所有的hotseats

loadHotseats();//从加载本地设置

checkForLocaleChange();setWallpaperDimension();//加载布局文件

setContentView(R.layout.launcher);//初始化所有控件

setupViews();

registerContentObservers();

lockAllApps();//从Bundle savedInstanceState获取桌面持久化数据

mSavedState =savedInstanceState;

restoreState(mSavedState);if(PROFILE_STARTUP) {

android.os.Debug.stopMethodTracing();

}if (!mRestoring) {//LauncherModel.Loader.startLoader() 代码同步处理

mModel.startLoader(this, true);

}//For handling default keys

mDefaultKeySsb = newSpannableStringBuilder();

Selection.setSelection(mDefaultKeySsb,0);//注册Intent.ACTION_CLOSE_SYSTEM_DIALOGS广播监听

IntentFilter filter = newIntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);

registerReceiver(mCloseSystemDialogsReceiver, filter);

}

第三步:加载桌面项:在LauncherModel.java的Thread的run方法,是在主线程完成以后才开始加载。

public voidrun() {//Optimize for end-user experience: if the Launcher is up and//running with the//All Apps interface in the foreground, load All Apps first. Otherwise, load the//workspace first (default).

final Callbacks cbk =mCallbacks.get();final boolean loadWorkspaceFirst = cbk != null ? (!cbk.isAllAppsVisible()) : true;

keep_running: {//Elevate priority when Home launches for the first time to avoid//starving at boot time. Staring at a blank home is not cool.

synchronized(mLock) {

android.os.Process.setThreadPriority(mIsLaunching?Process.THREAD_PRIORITY_DEFAULT : Process.THREAD_PRIORITY_BACKGROUND);

}//判断是否先加载桌面

if(loadWorkspaceFirst) {if (DEBUG_LOADERS) Log.d(TAG, "step 1: loading workspace");//从数据库launcher.db中查询中所有桌面项构造对应类型的ItemInfo对象存入

loadAndBindWorkspace();

}else{if (DEBUG_LOADERS) Log.d(TAG, "step 1: special: loading all apps");

loadAndBindAllApps();

}if(mStopped) {breakkeep_running;

}//Whew! Hard work done. Slow us down, and wait until the UI thread has//settled down.

synchronized(mLock) {if(mIsLaunching) {

android.os.Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);

}

}

waitForIdle();//second step

if(loadWorkspaceFirst) {if (DEBUG_LOADERS) Log.d(TAG, "step 2: loading all apps");

loadAndBindAllApps();

}else{if (DEBUG_LOADERS) Log.d(TAG, "step 2: special: loading workspace");

loadAndBindWorkspace();

}

}

这里调用了Launcher.java中startBinding方法

public voidstartBinding() {final Workspace workspace =mWorkspace;int count =workspace.getChildCount();for (int i = 0; i < count; i++) {//Use removeAllViewsInLayout() to avoid an extra requestLayout() and invalidate().

((ViewGroup) workspace.getChildAt(i)).removeAllViewsInLayout();

}if(DEBUG_USER_INTERFACE) {

android.widget.Button finishButton= new android.widget.Button(this);

finishButton.setText("Finish");

workspace.addInScreen(finishButton,1, 0, 0, 1, 1);

finishButton.setOnClickListener(newandroid.widget.Button.OnClickListener() {public voidonClick(View v) {

finish();

}

});

}

}

还有Launcher.java的bindItem()方法

public void bindItems(ArrayList shortcuts, int start, intend) {

setLoadOnResume();//获取桌面的celllayout对象,也就是workspace下5个用户桌面中的一个

final Workspace workspace =mWorkspace;for (int i=start; i

final ItemInfo item =shortcuts.get(i);

mDesktopItems.add(item);switch(item.itemType) {caseLauncherSettings.Favorites.ITEM_TYPE_APPLICATION:caseLauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:final View shortcut =createShortcut((ShortcutInfo)item);//获取item.screen, item.cellX, item.cellY, spanX, spanY并添加到屏幕上。

workspace.addInScreen(shortcut, item.screen, item.cellX, item.cellY, 1, 1,false);break;caseLauncherSettings.Favorites.ITEM_TYPE_USER_FOLDER:final FolderIcon newFolder = FolderIcon.fromXml(R.layout.folder_icon, this,

(ViewGroup) workspace.getChildAt(workspace.getCurrentScreen()),

(UserFolderInfo) item);

workspace.addInScreen(newFolder, item.screen, item.cellX, item.cellY,1, 1,false);break;caseLauncherSettings.Favorites.ITEM_TYPE_LIVE_FOLDER:final FolderIcon newLiveFolder =LiveFolderIcon.fromXml(

R.layout.live_folder_icon,this,

(ViewGroup) workspace.getChildAt(workspace.getCurrentScreen()),

(LiveFolderInfo) item);

workspace.addInScreen(newLiveFolder, item.screen, item.cellX, item.cellY,1, 1,false);break;

}

}//.重新设置桌面图标view 的layoutparam(类型为cellLayout.layoutparam)

workspace.requestLayout();

}

注意,这两个方法都是异步调用。原因应该很清楚:时间。

另外还要注意一下两点:

1.桌面图标view对象添加OnLongClickListener=laucher,由laucher负责监听桌面图标view的longclick事件

2.如果桌面图标是DropTarget对象,拖放控制器mDragController添加该view到拖放目的地列表

在Launcher.java的代码中有bindFolders()和bindAppWidget()方法,都是回调方法。主要看下bindAppWidget()方法吧。

/*** Add the views for a widget to the workspace.

*

* Implementation of the method from LauncherModel.Callbacks.*/

public voidbindAppWidget(LauncherAppWidgetInfo item) {

setLoadOnResume();final long start = DEBUG_WIDGETS ? SystemClock.uptimeMillis() : 0;if(DEBUG_WIDGETS) {

Log.d(TAG,"bindAppWidget: " +item);

}final Workspace workspace =mWorkspace;//获取LauncherAppWidgetInfo的appWidgetId

final int appWidgetId =item.appWidgetId;//根据appWidgetInfo创建桌面组件的view AppWidgetHostView对象

final AppWidgetProviderInfo appWidgetInfo =mAppWidgetManager.getAppWidgetInfo(appWidgetId);if(DEBUG_WIDGETS) {

Log.d(TAG,"bindAppWidget: id=" + item.appWidgetId + " belongs to component " +appWidgetInfo.provider);

}

item.hostView= mAppWidgetHost.createView(this, appWidgetId, appWidgetInfo);

item.hostView.setAppWidget(appWidgetId, appWidgetInfo);

item.hostView.setTag(item);//添加到对应桌面的cell

workspace.addInScreen(item.hostView, item.screen, item.cellX,

item.cellY, item.spanX, item.spanY,false);

workspace.requestLayout();

mDesktopItems.add(item);if(DEBUG_WIDGETS) {

Log.d(TAG,"bound widget id="+item.appWidgetId+" in "

+ (SystemClock.uptimeMillis()-start) + "ms");

}

}

当都加载完成以后会执行finishBindingItems():

/*** Callback saying that there aren't any more items to bind.

*

* Implementation of the method from LauncherModel.Callbacks.*/

public voidfinishBindingItems() {

setLoadOnResume();if (mSavedState != null) {if (!mWorkspace.hasFocus()) {

mWorkspace.getChildAt(mWorkspace.getCurrentScreen()).requestFocus();

}final long[] userFolders =mSavedState.getLongArray(RUNTIME_STATE_USER_FOLDERS);if (userFolders != null) {for (longfolderId : userFolders) {final FolderInfo info =sFolders.get(folderId);if (info != null) {

openFolder(info);

}

}final Folder openFolder =mWorkspace.getOpenFolder();if (openFolder != null) {

openFolder.requestFocus();

}

}

mSavedState= null;

}if (mSavedInstanceState != null) {super.onRestoreInstanceState(mSavedInstanceState);

mSavedInstanceState= null;

}

mWorkspaceLoading= false;

}

前面那三个都是都是回调方法,控制器当然是LauncherModel.java了,让我们在代码里看一下:

其接口定义如下:

public interfaceCallbacks {public booleansetLoadOnResume();public intgetCurrentWorkspaceScreen();public voidstartBinding();public void bindItems(ArrayList shortcuts, int start, intend);public void bindFolders(HashMapfolders);public voidfinishBindingItems();public voidbindAppWidget(LauncherAppWidgetInfo info);public void bindAllApplications(ArrayListapps);public void bindAppsAdded(ArrayListapps);public void bindAppsUpdated(ArrayListapps);public void bindAppsRemoved(ArrayList apps, booleanpermanent);public booleanisAllAppsVisible();

}

想看仔细的,自己可以在代码中找一下。最后执行bindAllApplications(),bindAppsAdded()方法:

public void bindAllApplications(ArrayListapps) {

mAllAppsGrid.setApps(apps);

}/*** A package was installed.

*

* Implementation of the method from LauncherModel.Callbacks.*/

public void bindAppsAdded(ArrayListapps) {

setLoadOnResume();

removeDialog(DIALOG_CREATE_SHORTCUT);

mAllAppsGrid.addApps(apps);

}

到这基本上就是整个的启动过程了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值