(1)      Launcher的定义:Android系统启动后,加载的第一个程序,是其他应用程序的入口。

(2)      Launcher的构成:HomeScreen(1.workspace(AppWidget,Wallpaper,Livefolder,ShortCut),2.HotSeats,3.AllApps/allApplist:GridView)

(3)      针对Launcher的开发类型:

1.      开发自定义的Launcher

2.      与Workspace相关的开发(AppWidget,Wallpaper,Livefolder,ShortCut)

(4)      解读Launcher源代码(以ShortCut为例),Launcher为系统级应用,位于Applications层。源代码位于MyAndroid\packages\apps\Launcher2中,可讲它导入eclipse中。

(5)      看Manifest文件可知,Launcher的主Activity为:com.android.launcher2.Launcher。下面是它的部分配置信息:

<activity
android:name="com.android.launcher2.Launcher"
android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.MONKEY"/>
</intent-filter>
</activity>

(6)      关于Activity的四种加载模式(android:launchMode):在多Activity开发中,有可能是自己应用之间的Activity跳转,或者夹带其他应用的可复用Activity。有可能会希望跳转到原来某个Activity实例,而不是产生大量重复的Activity。这就需要为Activity配置特定的加载模式,而不是默认的加载模式。

1.      Standard:默认模式,每次激活Activity时都会创建Activity,并放入任务栈中。

2.      singleTop:如果在任务栈栈顶正好存在该Activity的实例,就重用该实例(会调用实例的onNewIntent()),否则就会创建新的实例并放入栈顶,即使栈中已经存在该Activity的实例。

3.      singleTask:如果在栈中已经有该Activity的实例,就会重用该实例,重用时,会让该实例回到栈顶,因此在它上面的实例将会被移出栈。

4.      singleInstance:在一个新栈中创建该Activity的实例,并让多个应用共享该栈中的该Activity实例。一旦该模式的Activity实例已经存在于某个栈中,任何应用再激活该Activity时都会重用该栈中的实例( 会调用实例的onNewIntent() )。其效果相当于多个应用共享一个应用,不管谁激活该 Activity 都会进入同一个应用中。

(7)      当用户按菜单键中的添加按钮或者长按workspace中的空白区域,会弹出一个对话框(如下图所示):

@Override
publicbooleanonOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
caseMENU_ADD:
addItems(); /* 按菜单键,添加按钮*/
returntrue;
caseMENU_MANAGE_APPS:
manageApps();
returntrue;
caseMENU_WALLPAPER_SETTINGS:
startWallpaper();
returntrue;
caseMENU_SEARCH: @Override
publicbooleanonOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
caseMENU_ADD:
addItems(); /* 按菜单键,添加按钮*/
returntrue;
caseMENU_MANAGE_APPS:
manageApps();
returntrue;
caseMENU_WALLPAPER_SETTINGS:
startWallpaper();
returntrue;
caseMENU_SEARCH:
onSearchRequested();
returntrue;
caseMENU_NOTIFICATIONS:
showNotifications();
returntrue;
} returnsuper.onOptionsItemSelected(item);
} privatevoidaddItems() {
closeAllApps(true);
showAddDialog(mMenuAddInfo); /* 显示对话框 */
} // 长按workspace空白区域
if (mWorkspace.allowLongPress()) {
if (cellInfo.cell == null) {
if (cellInfo.valid) {
// User long pressed on empty space
mWorkspace.setAllowLongPress(false);
mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,
HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
showAddDialog(cellInfo);/* 显示对话框 */
}
} else {
if (!(cellInfo.cellinstanceof Folder)) {
// User long pressed on an item
mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,
HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
mWorkspace.startDrag(cellInfo);
}
}
}
// showAddDialog方法
privatevoidshowAddDialog(CellLayout.CellInfocellInfo) {
mAddItemCellInfo = cellInfo;
mWaitingForResult = true;
showDialog(DIALOG_CREATE_SHORTCUT);
} // showDialog方法会调用下面这个方法创建对话框
protected Dialog onCreateDialog(int id) {
switch (id) {
caseDIALOG_CREATE_SHORTCUT: // 注意这里的常量
returnnewCreateShortcut().createDialog();
caseDIALOG_RENAME_FOLDER:
returnnewRenameFolder().createDialog();
} returnsuper.onCreateDialog(id);
} // CreateShortcut为Launcher的内部类,看其中的pickShortcut()
// 方法,它实现很多接口 /**
* Displays the shortcut creation dialog and launches, if necessary, theappropriate activity.
*/
privateclassCreateShortcutimplementsDialogInterface.OnClickListener,
DialogInterface.OnCancelListener, DialogInterface.OnDismissListener,
DialogInterface.OnShowListener { privateAddAdaptermAdapter; Dialog createDialog() {
mAdapter = newAddAdapter(Launcher.this); finalAlertDialog.Builder builder = newAlertDialog.Builder(Launcher.this);
builder.setTitle(getString(R.string.menu_item_add_item));
builder.setAdapter(mAdapter, this); builder.setInverseBackgroundForced(true); AlertDialog dialog = builder.create();
dialog.setOnCancelListener(this);
dialog.setOnDismissListener(this);
dialog.setOnShowListener(this); return dialog;
} publicvoidonCancel(DialogInterface dialog) {
mWaitingForResult = false;
cleanup();
} publicvoidonDismiss(DialogInterface dialog) {
} privatevoid cleanup() {
try {
dismissDialog(DIALOG_CREATE_SHORTCUT);
} catch (Exception e) {
// An exception is thrown if the dialog is not visible, which is fine
}
} /**
* Handle the action clicked in the “Add to home” dialog.
*/
publicvoidonClick(DialogInterface dialog, int which) {
Resources res = getResources();
cleanup(); switch (which) {
caseAddAdapter.ITEM_SHORTCUT: {
// Insert extra item to handle picking application
pickShortcut(); //当点击对话框中的快捷方式项,会//调用此方法
break;
} caseAddAdapter.ITEM_APPWIDGET: {
intappWidgetId = Launcher.this.mAppWidgetHost.allocateAppWidgetId(); Intent pickIntent = new Intent(AppWidgetManager.ACTION_APPWIDGET_PICK);
pickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
// start the pick activity
startActivityForResult(pickIntent, REQUEST_PICK_APPWIDGET);
break;
} caseAddAdapter.ITEM_LIVE_FOLDER: {
// Insert extra item to handle inserting folder
Bundle bundle = new Bundle(); ArrayList<String>shortcutNames = newArrayList<String>();
shortcutNames.add(res.getString(R.string.group_folder));
bundle.putStringArrayList(Intent.EXTRA_SHORTCUT_NAME, shortcutNames); ArrayList<ShortcutIconResource>shortcutIcons =
newArrayList<ShortcutIconResource>();
shortcutIcons.add(ShortcutIconResource.fromContext(Launcher.this,
R.drawable.ic_launcher_folder));
bundle.putParcelableArrayList(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, shortcutIcons); Intent pickIntent = new Intent(Intent.ACTION_PICK_ACTIVITY);
pickIntent.putExtra(Intent.EXTRA_INTENT,
new Intent(LiveFolders.ACTION_CREATE_LIVE_FOLDER));
pickIntent.putExtra(Intent.EXTRA_TITLE,
getText(R.string.title_select_live_folder));
pickIntent.putExtras(bundle); startActivityForResult(pickIntent, REQUEST_PICK_LIVE_FOLDER);
break;
} caseAddAdapter.ITEM_WALLPAPER: {
startWallpaper();
break;
}
}
} publicvoidonShow(DialogInterface dialog) {
mWaitingForResult = true;
}
} // pickShortcut()方法
privatevoidpickShortcut() {
Bundle bundle = new Bundle(); ArrayList<String>shortcutNames = newArrayList<String>();
shortcutNames.add(getString(R.string.group_applications));
bundle.putStringArrayList(Intent.EXTRA_SHORTCUT_NAME, shortcutNames); ArrayList<ShortcutIconResource>shortcutIcons = newArrayList<ShortcutIconResource>();
shortcutIcons.add(ShortcutIconResource.fromContext(Launcher.this,
R.drawable.ic_launcher_application));
bundle.putParcelableArrayList(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, shortcutIcons); Intent pickIntent = new Intent(Intent.ACTION_PICK_ACTIVITY);
pickIntent.putExtra(Intent.EXTRA_INTENT, new Intent(Intent.ACTION_CREATE_SHORTCUT));
pickIntent.putExtra(Intent.EXTRA_TITLE, getText(R.string.title_select_shortcut));
pickIntent.putExtras(bundle); startActivityForResult(pickIntent,REQUEST_PICK_SHORTCUT); // 启动了一个Activity,其实是一个快捷方式//列表,一个回调方法
} // 在onActivityResult()中 caseREQUEST_PICK_SHORTCUT:
processShortcut(data); // 回调此方法,data为Intent
break; voidprocessShortcut(Intent intent) {
// Handle case where user selected "Applications"
String applicationName = getResources().getString(R.string.group_applications);
String shortcutName = intent.getStringExtra(Intent.EXTRA_SHORTCUT_NAME); if (applicationName != null&&applicationName.equals(shortcutName)) {
Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
mainIntent.addCategory(Intent.CATEGORY_LAUNCHER); Intent pickIntent = new Intent(Intent.ACTION_PICK_ACTIVITY);
pickIntent.putExtra(Intent.EXTRA_INTENT, mainIntent);
pickIntent.putExtra(Intent.EXTRA_TITLE, getText(R.string.title_select_application));
startActivityForResultSafely(pickIntent, REQUEST_PICK_APPLICATION);
} else {
startActivityForResultSafely(intent, REQUEST_CREATE_SHORTCUT); //这里还要启动一个Activity
}
} caseREQUEST_CREATE_SHORTCUT:
completeAddShortcut(data, mAddItemCellInfo);
break; /**
* Add a shortcut to the workspace.
*
* @param data The intent describing the shortcut.
* @paramcellInfo The position on screen where to create the shortcut.
*/
privatevoidcompleteAddShortcut(Intent data, CellLayout.CellInfocellInfo) {
cellInfo.screen = mWorkspace.getCurrentScreen();
if (!findSingleSlot(cellInfo)) return; finalShortcutInfo info = mModel.addShortcut(this, data, cellInfo, false); if (!mRestoring) {
final View view = createShortcut(info);
mWorkspace.addInCurrentScreen(view, cellInfo.cellX, cellInfo.cellY, 1, 1,
isWorkspaceLocked());
}
}

(8)      如何让你的应用支持创建Shortcut,即你的应用能够出现在快捷方式列表中。

//  单独创建一个Activity,例如ShortCut.java
// 配置此Activity
<activity
android:name=".ShortCut">
<intent-filter>
<actionandroid:name="android.intent.action.CREATE_SHORTCUT"/>
</intent-filter>
</activity>
// 以下是它的代码,这个startActivityForResultSafely(intent, //REQUEST_CREATE_SHORTCUT)方法会跳到这个Activity
publicclassShortCutextends Activity { @Override
protectedvoidonCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(getIntent().getAction().equals(Intent.ACTION_CREATE_SHORTCUT)) {
Intent returnIntent = new Intent();
returnIntent.putExtra(Intent.EXTRA_SHORTCUT_NAME, "应用管理器");
returnIntent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, new Intent(this, ShowAppActivity.class));
/* returnIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE,
Intent.ShortcutIconResource.fromContext(this, R.drawable.icon)); */
returnIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON, R.drawable.icon);
setResult(RESULT_OK, returnIntent);
finish();
}
} }

(9)      如何在用户第一次启动应用后,提示用户是否要创建Shortcut:现在Manifest文件中添加一个权限(<permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT"></permission>)只要向Launcher发送一个广播,数据为一个Intent。此Intent与上面代码中的returnIntent类似,只要这个Intent添加一个Action(

intent.setAction("com.android.launcher.action.INSTALL_SHORTCUT"))。然后sendBroadcast(intent)。在Launcher中有个InstallShortcutReceiver.java,接受这个广播。

Android Launcher 详解的更多相关文章

  1. Android——Android Bundle详解(转)

    Android Bundle详解 1 Bundle介绍 Bundle主要用于传递数据:它保存的数据,是以key-value(键值对)的形式存在的. 我们经常使用Bundle在Activity之间传递数 ...

  2. Android Notification 详解(一)——基本操作

    Android Notification 详解(一)--基本操作 版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/Notification 文中如有纰 ...

  3. Android Notification 详解——基本操作

    Android Notification 详解 版权声明:本文为博主原创文章,未经博主允许不得转载. 前几天项目中有用到 Android 通知相关的内容,索性把 Android Notificatio ...

  4. Android ActionBar详解

    Android ActionBar详解 分类: Android2014-04-30 15:23 1094人阅读 评论(0) 收藏 举报 androidActionBar   目录(?)[+]   第4 ...

  5. Android 签名详解

    Android 签名详解 AndroidOPhoneAnt设计模式Eclipse  在Android 系统中,所有安装 到 系统的应用程序都必有一个数字证书,此数字证书用于标识应用程序的作者和在应用程 ...

  6. Android编译系统详解(一)

    ++++++++++++++++++++++++++++++++++++++++++ 本文系本站原创,欢迎转载! 转载请注明出处: http://blog.csdn.net/mr_raptor/art ...

  7. Android布局详解之一:FrameLayout

      原创文章,如有转载,请注明出处:http://blog.csdn.net/yihui823/article/details/6702273 FrameLayout是最简单的布局了.所有放在布局里的 ...

  8. 【整理修订】Android.mk详解

    Android.mk详解 1. Android.mk 的应用范围 Android.mk文件是GNU Makefile的一小部分,它用来对Android程序进行编译. 一个Android.mk文件可以编 ...

  9. Android菜单详解(四)——使用上下文菜单ContextMenu

    之前在<Android菜单详解(二)——创建并响应选项菜单>和<Android菜单详解(三)——SubMenu和IconMenu>中详细讲解了选项菜单,子菜单和图标菜单.今天接 ...

随机推荐

  1. Qt之Meta-Object系统

    简述 Qt的元对象系统(Meta-Object System)提供了信号与槽机制,可用于对象间通信.运行时类别信息和动态属性系统. 元对象系统基于三个方面: QObject类:为objects提供了一 ...

  2. --专访雷果国: 从1.5K到18K 一个程序员的5年成长之路--

    导语:今年三月份,在CSDN博客和新浪微博上有一篇<从1.5K到18K,一个程序员的5年成长之路>被众人分享和传阅,这篇博文首先介绍了作者自学之初薄弱的基础,然后通过流水账形式分享了那个从 ...

  3. 10个必备的移动UI设计资源站(转)

    创建移动设计模式是非常重要的一步,记住!这是为移动设备设计而不是web.不仅仅是移动屏幕远小于普通的电脑屏幕,关键是鼠标和键盘已经被手指替代了! 当然还有更重要的,说起来很苦逼,我们再也不能使用一种模 ...

  4. ios基础篇(九)——自定义UITabBar

    上一篇讲到了UITabBarViewController,接着说说UITabBarViewController中怎么自定义TabBar. 今天仿写了微博,发现底部tabbar中间的button和其他有 ...

  5. lucene底层数据结构——底层filter bitset原理,时间序列数据压缩将同一时间数据压缩为一行

    如何联合索引查询? 所以给定查询过滤条件 age=18 的过程就是先从term index找到18在term dictionary的大概位置,然后再从term dictionary里精确地找到18这个 ...

  6. C#读取Xml【转】

      XML文件是一种常用的文件格式,例如WinForm里面的app.config以及Web程序中的web.config文件,还有许多重要的场所都有它的身影.Xml是Internet环境中跨平台的,依赖 ...

  7. FZU 2028 时空门问题

    题目链接:时空门问题 简单bfs,每个格子移动的方式除了上下左右,还有时空门,开始想着用邻接表保存每个点能通过时空门到达的点就ok了.很快的敲出来,很快的WA了.长久的dbug并没有发现error.然 ...

  8. bzoj 2241: [SDOI2011]打地鼠

    #include<cstdio> #include<iostream> using namespace std; ][],b[][],ans,sum; void pan(int ...

  9. bzoj 2132: 圈地计划

    #include<cstdio> #include<iostream> #include<cstring> #define M 100009 #define inf ...

  10. 2014北邮新生归来赛解题报告d-e

    D: 399. Who Is Joyful 时间限制 3000 ms 内存限制 65536 KB 题目描述 There are several little buddies standing in a ...