androidlauncher分析
㈠ 请先运行launcher是什么意思
launcher的意思是请先运行启动器、桌面引擎。
详解如下:
launcher
一、读音:
['lɔːn(t)ʃə]
二、释义:
1.n.发射器;发射器
2.起动器
3.发射基地
三、短语
1.导弹发射器导弹发射器;导弹发射器;火箭发射器
2.Zeam桌面管家;美化桌面;本地化版本;面对管家
3.MXHome启动MX桌面
4.Xperialauncher索尼爱立信桌面;起动器
5.应用程序启动器;起动器;应用程序管理器;应用程序调用模块
LMT启动器全屏幕助手
7.去启动去桌面;去桌面前
8.XUS桌面美化工具;桌面美化图标管理;美化软件的快捷方式
9.发射塔发射器军事发射塔发射器
换句话说,Launcher是androidzd中的主要程序组件之一,而android的内部系统没有Launcher就无法启动android桌面,一旦出错,android就会有“进程容量”com.android.launcher“意外停止”的提示窗口。
(1)androidlauncher分析扩展阅读
同义词:
catapult
一、读音:
英['kætəpʌlt]美['kætəpʌlt]
二、释义:
1、n.弹弓;石弩;(从舰船上弹射飞机的)弹射器;(飞机上的)座椅弹射器
2、v.猛投;用弹弓射,用弹射器发射;(仿佛被弹射般地)突然快速移动;使突然处于
三、短语
1、CatapultKing弹射之王;弹射王国;弹弓王;弩车之王
2、CatapultShip弩炮船;投石船
3、glidercatapult滑翔机弹射器
4、ShurikenCatapult星镖射枪;星镖步枪
5、MonkeyCatapult猴子弹射
6、steamcatapult蒸汽弹射器
7、catapultplants弹射器厂;弹射植物
8、catapultdamage弹射器损坏
8、catapultstrip弹弓橡皮筋
㈡ launcher是什么意思
launcher的意思是安卓系统桌面启动器。
Launcher是安卓系统中的桌面启动器,安卓系统的桌面UI统称为Launcher。Launcher是安卓系统中的主要程序组件之一。
安卓系统中如果没有Launcher就无法启动安卓桌面,Launcher出错的时候,安卓系统会出现“进程 com.android.launcher 意外停止”的提示窗口。这时需要重新启动Launcher。
特点:
DragLayer实际上也是一个抽象的界面,用来处理拖动和对事件进行初步处理然后按情况分发下去,角色是一个controller。它首先用onInterceptTouchEvent(MotionEvent)来拦截所有的touch事件。
如果是长按item拖动的话不把事件传下去,直接交由onTouchEvent()处理。这样就可以实现item的移动了,如果不是拖动item的话就把事件传到目标view。
交有目标view的事件处理函数做相应处理。如果有要对事件的特殊需求的话可以修改onInterceptTouchEvent(MotionEvent)来实现所需要的功能。
以上内容参考网络—launcher
㈢ android源码中有launcher2launcher3,用的是哪个
1、Launcher进程启动过程
可以由下面图看到Launcher进程是如何被创建启动:
Activity Manager通过发送Intend来启动Launcher。
Intent intent = new Intent(mTopAction, mTopData != null ?
Uri.parse(mTopData) : null);
intent.setComponent(mTopComponent);
if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL)
{
intent.addCategory(Intent.CATEGORY_HOME);
}
startActivityLocked(null, intent, null, null, 0, aInfo,
null, null, 0, 0, 0, false, false);
复制代码
因此,如果你要开机启动一个替换Launcher的程序,只要在程序<intent-filter>里面加入action.MAIN 、
category.HOME、category.DEFAULT就可以。如果出现多个程序都加入这种intent,系统会弹出让你选择
哪个作为启动器。
2、Launcher初始化——LauncherApplication。
Application类,我想大部分做Android应用的朋友都用过,每个Android应用默认都有一个Application类,
你也可以继承Application类,然后加入自己代码。Application是一个全局的应用类,在AndroidManifest.xml
我们也可以找到Application标签。
<application
android:name="com.android.launcher2.LauncherApplication"
android:label="@string/application_name"
android:icon="@drawable/ic_launcher_home"
android:hardwareAccelerated="@bool/config_hardwareAccelerated"
android:largeHeap="@bool/config_largeHeap"
android:configChanges="locale">
</application>
复制代码
Android四大组件的声明都需要放到application标签里面,默认使用的是系统的Application类,如果你在项目里面重载了它。就需要在标签,name属性下写上你的新的Application类名。Launcher里面就是继承了Application为LauncherApplication。应用启动的时候首先会加载Application。我们可以看到Launcher主类Launcher.java的onCreate函数里面,第一个就是获取Application的实例。
LauncherApplication app = ((LauncherApplication)getApplication());
复制代码
接下来我们看看LauncherApplication里面初始化,LauncherApplication大部分工作就是在初始化完成,剩下都是一些返回接口。
@Override
public void onCreate()
{
super.onCreate();
//获取屏幕大小,主要用来区分手机还是平板
final int screenSize = getResources().getConfiguration().screenLayout &
Configuration.SCREENLAYOUT_SIZE_MASK;
sIsScreenLarge = screenSize == Configuration.SCREENLAYOUT_SIZE_LARGE ||
screenSize == Configuration.SCREENLAYOUT_SIZE_XLARGE;
//屏幕密度
sScreenDensity = getResources().getDisplayMetrics().density;
//IconCahe里面保存了界面所有应用图标的绘画需要的数据,这个到时候具体分析再说。
//加入这东西的主要原因是为了提高绘画界面的效率
mIconCache = new IconCache(this);
//数据库加载类,LauncherModel是Launcher里面非常重要的一个类,相当于MVC模式里面的
//Model功能,管理数据和初始化数据
mModel = new LauncherModel(this, mIconCache);
//下面注册了一些监听器,主要包含APK文件更新删除等数据变化的时候接收的通知
//接收通知后,主要是用来更新Launcher里面的数据库。因为桌面应用图标数据,只会加载一次
IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
filter.addDataScheme("package");
registerReceiver(mModel, filter);
filter = new IntentFilter();
filter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);
filter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
filter.addAction(Intent.ACTION_LOCALE_CHANGED);
filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
registerReceiver(mModel, filter);
filter = new IntentFilter();
filter.addAction(SearchManager.INTENT_GLOBAL_SEARCH_ACTIVITY_CHANGED);
registerReceiver(mModel, filter);
filter = new IntentFilter();
filter.addAction(SearchManager.INTENT_ACTION_SEARCHABLES_CHANGED);
registerReceiver(mModel, filter);
//contentresolver则是用于管理所有程序的contentprovider实例
ContentResolver resolver = getContentResolver();
//注册内容观察者,监听application数据库变化,回调
resolver.registerContentObserver(LauncherSettings.Favorites.CONTENT_URI, true, mFavoritesObserver);
}
复制代码
上面是LauncherApplication最主要的工作,初始化整个Launcher的一些关键类,和注册一些监听器。主要都是用来监听应用的安装更新删除等导致Launcher数据库变化的操作。Launcher数据都是使用contentprovider来提供数据。其中注册的监听接口是
private final ContentObserver mFavoritesObserver = new ContentObserver(new Handler())
{
@Override
public void onChange(boolean selfChange)
{
//重新加载界面数据
mModel.startLoader(LauncherApplication.this, false);
}
};
复制代码
LauncherSettings.Favorites.CONTENT_URI里面数据发生变化的时候,都会调用mModel.startLoader()接口,
重新加载Launcher的数据。startLoader的具体操作,我后面分析LauncherModel类的时候会分析。这一块涉及
Launcher所有数据加载。剩下的接都是返回初始化时候创建的对象或者获取屏幕密度、获取是否大屏幕。
后面很多处理都需要判断是否是大屏幕,4.0以后手机平板都共用一套系统,导致多了很多处理。 3、Launcher.java初始化Launcher.java是Launcher里面最主要的类,是一个Activity。启动的第一个组件。既然是Activity,我们要分析它初始化,毫无疑问,需要找到onCreate()里面分析。把主要一些分析用注释方式写在代码里面,这样比较方便阅读。
㈣ 如何修改调整android 4.0 launcher 桌面图标快捷方式的大小综合
/packages/apps/Launcher/res/xml/default_workspace.xml中记录了系统初始化或者恢复出厂设置时桌面上图标的排列。Launcher程序第一次运行完毕以后,会在/data/data/com.android.launcher/databases/launcher.db中创建记录,里面有所有当前的桌面图标。以后每次启动只会从这里读取桌面图标。
下面简单分析一下default_workspace.xml:
default_workspace.xml中,支持的标签有:
favorite:应用程序快捷方式。
shortcut:链接,如网址,本地磁盘路径等。
search:搜索框。
clock:桌面上的钟表Widget
支持的属性有:
launcher:title,图标下面的文字,目前只支持引用,不能直接书写字符串。
launcher:icon,图标引用。
launcher:uri,链接地址。
launcher:packageName,应用程序的包名。
launcher:className,应用程序的启动类名。
launcher:screen,图标所在的屏幕编号。
launcher:x,图标在横向排列上的序号。
launcher:y,图标在纵向排列上的序号。
LauncherProvider.java里面的loadFavorites方法负责解析。
应用程序的写法,default_workspace.xml中有很多,对链接的写法却没有,我分析了一下它的解析程序,反向做出了链接快捷方式的写法,已经验证成功,希望可以帮到大家。
<shortcut
launcher:title="@string/aaa"
launcher:icon="@drawable/aaa"
launcher:uri="http://www.aaa.com"
launcher:screen="1"
launcher:x="0"
launcher:y="3" />
链接的图标内容和文字内容是从default_workspace.xml中获取到的。
应用程序的图标内容和图标下面的文字内容都是从PackageManager中获取到的。
如果Launcher启动时,应用程序的包名和类名因为某种原因没有在PackageManager中找到,桌面就不会显示它的图标。如果类名和包名找到了,但是图标没有找到,会显示Android默认的小机器人图标。
所以,要在default_workspace.xml中加入锭接时,只要写上title,icon,uri,screen,x,y这几个属性就可以了。
而要加入应用程序时,只要写上packageName,className,screen,x,y这几个属性就可以了。
㈤ android launcher 什么时候启动
Android系统的Home应用程序Launcher是由ActivityManagerService启动的,而ActivityManagerService和PackageManagerService一样,都是在开机时由SystemServer组件启动的,SystemServer组件首先是启动ePackageManagerServic,由它来负责安装系统的应用程序,具体可以参考前面一篇文章Android应用程序安装过程源代码分析,系统中的应用程序安装好了以后,SystemServer组件接下来就要通过ActivityManagerService来启动Home应用程序Launcher了,Launcher在启动的时候便会通过PackageManagerServic把系统中已经安装好的应用程序以快捷图标的形式展示在桌面上,这样用户就可以使用这些应用程序了
㈥ android launcher2 launcher 有什么不同
launcher不支持桌面小工具动画效果,launcher2添加了动画效果和3D初步效果支持。还有,launcher2的滑动效果有所改善。
㈦ android Launcher的滑动效果怎么实现
滑动功能主要分两步:
1、在onInterceptTouchEvent中进行拦截。
2、在onTouchEvent中进行滑动。
1,onInterceptTouchEvent(MotionEvent en)
在这个方法中,决定了什么时候截获MotionEvent来实现滑动,避免了子View的其他事件的影响(如点击事件)。
[java] view plain
public boolean onInterceptTouchEvent(MotionEvent ev) {
/**
* This method JUST determines whether we want to intercept the motion.
* If we return true, onTouchEvent will be called and we do the actual
* scrolling there.
**/
//获取速度跟踪器,记录各个时刻的速度。并且添加当前的MotionEvent以记录更行速度值。
(ev);
......
/**
* Shortcut the most recurring case: the user is in the dragging
* state and he is moving his finger. We want to intercept this
* motion.
* 最常见的需要拦截的情况:用户已经进入滑动状态,并且正在滑动手指。
* 对这种情况直接进行拦截,执行onTouchEvent()继续执行滑动操作。
**/
final int action = ev.getAction();
if ((action == MotionEvent.ACTION_MOVE) &&
(mTouchState == TOUCH_STATE_SCROLLING)) {
return true;
}
switch (action & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_MOVE: {
/**
* mIsBeingDragged == false, otherwise the shortcut would have caught it. Check
* whether the user has moved far enough from his original down touch.
*/
/**
* 当在这里接受到ACTION_MOVE时,说明mTouchState!=TOUCH_STATE_SCROLLING并且mIsBeingDragged的值应该为false,
* 否则DragLayer就应该截获了MotionEvent用于实现拖拽。
* 此时还没有进入滑动状态,当mActivePointerId == INVALID_POINTER时,也就是在此之前没有接收到任何touch事件。
* 这种情况发生在Workspace变小时,也就是之前Workspace处于SPRING_LOADED状态。当出现这种情况时直接把当前的事件当作ACTION_DOWN进行处理。
* 反之,则通过determineScrollingStart()尝试能够进入滑动状态。
*/
if (mActivePointerId != INVALID_POINTER) {
determineScrollingStart(ev);
break;
}
// if mActivePointerId is INVALID_POINTER, then we must have missed an ACTION_DOWN
// event. in that case, treat the first occurence of a move event as a ACTION_DOWN
// i.e. fall through to the next case (don't break)
// (We sometimes miss ACTION_DOWN events in Workspace because it ignores all events
// while it's small- this was causing a crash before we checked for INVALID_POINTER)
}
case MotionEvent.ACTION_DOWN: {
final float x = ev.getX();
final float y = ev.getY();
// Remember location of down touch
//记录按下的x的坐标值
mDownMotionX = x;
//记录前次发生touch时的坐标
mLastMotionX = x;
mLastMotionY = y;
//因为在ScrollBy时只能使用int,而记录的x和y都是float,会产生误差,故这里用mLastMotionXRemainder记录余数
//用于消除误差
mLastMotionXRemainder = 0;
//x方向上的总位移
mTotalMotionX = 0;
mActivePointerId = ev.getPointerId(0);
//设置mAllowLongPress=true,允许LongClick事件发生。LongClick事件定义在Launcher中
//处理的内容包括启动对shortcut的拖拽或弹出壁纸选择的对话框,若mAllowLongPress=false,
//则不会响应以上事件。
mAllowLongPress = true;
/**
* If being flinged and user touches the screen, initiate drag;
* otherwise don't. mScroller.isFinished should be false when
* being flinged.
* 当屏幕处于flinged状态(快速滑动)时,若此时用户触摸了屏幕,需要使滑动停止。
* 并且初始化拖拽的条件
**/
final int xDist = Math.abs(mScroller.getFinalX() - mScroller.getCurrX());
final boolean finishedScrolling = (mScroller.isFinished() || xDist < mTouchSlop);
if (finishedScrolling) {
mTouchState = TOUCH_STATE_REST;
mScroller.abortAnimation();
} else {
mTouchState = TOUCH_STATE_SCROLLING;
}
// check if this can be the beginning of a tap on the side of the pages
// to scroll the current page
if (mTouchState != TOUCH_STATE_PREV_PAGE && mTouchState != TOUCH_STATE_NEXT_PAGE) {
if (getChildCount() > 0) {
if (hitsPreviousPage(x, y)) {
mTouchState = TOUCH_STATE_PREV_PAGE;
} else if (hitsNextPage(x, y)) {
mTouchState = TOUCH_STATE_NEXT_PAGE;
}
}
}
break;
}
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
mTouchState = TOUCH_STATE_REST;
mAllowLongPress = false;
mActivePointerId = INVALID_POINTER;
releaseVelocityTracker();
break;
case MotionEvent.ACTION_POINTER_UP:
onSecondaryPointerUp(ev);
releaseVelocityTracker();
break;
}
/**
* The only time we want to intercept motion events is if we are in the
* drag mode.
* 只有进入了滑动状态,才进行拦截,进入onTouchEvent执行滑动操作。当mTouchState != TOUCH_STATE_REST
* 时,就说明没有进入滑动状态。
**/
return mTouchState != TOUCH_STATE_REST;
}
2,onTouchEvent(MotionEvent en)
在这个方法中,执行各种关于滑动的工作的计算,界面的刷新等工作。
[java] view plain
public boolean onTouchEvent(MotionEvent ev) {
......
switch (action & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
/*
* If being flinged and user touches, stop the fling. isFinished
* will be false if being flinged.
*/
/**
* 如果Workspace此时已经被“掷出去”(靠惯性滑动)。
* 此时发生ACTION_DOWN则需要停止滑动。
*/
if (!mScroller.isFinished()) {
mScroller.abortAnimation();
}
// Remember where the motion event started
mDownMotionX = mLastMotionX = ev.getX();
mLastMotionXRemainder = 0;
mTotalMotionX = 0;
mActivePointerId = ev.getPointerId(0);
if (mTouchState == TOUCH_STATE_SCROLLING) {
pageBeginMoving();
}
break;
case MotionEvent.ACTION_MOVE:
if (mTouchState == TOUCH_STATE_SCROLLING) {
......
if (Math.abs(deltaX) >= 1.0f) {
......
if (!mDeferScrollUpdate) {
//调用scrollBy滑动桌面
scrollBy((int) deltaX, 0);
......
} else {
......
}
mLastMotionX = x;
mLastMotionXRemainder = deltaX - (int) deltaX;
} else {
awakenScrollBars();
}
} else {
/**
* 如果条件满足,则进入滑动状态,开始滑动。
*/
determineScrollingStart(ev);
}
break;
case MotionEvent.ACTION_UP:
if (mTouchState == TOUCH_STATE_SCROLLING) {
......
boolean isSignificantMove = Math.abs(deltaX) > MIN_LENGTH_FOR_MOVE;
boolean returnToOriginalPage = false;
final int pageWidth = getScaledMeasuredWidth(getPageAt(mCurrentPage));
if (Math.abs(deltaX) > pageWidth * RETURN_TO_ORIGINAL_PAGE_THRESHOLD &&
Math.signum(velocityX) != Math.signum(deltaX)) {
returnToOriginalPage = true;
}
boolean isFling = mTotalMotionX > MIN_LENGTH_FOR_FLING &&
Math.abs(velocityX) > snapVelocity;
int finalPage;
//判断拿起手指之后应该进入哪个分屏
if (((isSignificantMove && deltaX > 0 && !isFling) ||
(isFling && velocityX > 0)) && mCurrentPage > 0) {
finalPage = returnToOriginalPage ? mCurrentPage : mCurrentPage - 1;
snapToPageWithVelocity(finalPage, velocityX);
} else if (((isSignificantMove && deltaX < 0 && !isFling) ||
(isFling && velocityX < 0)) &&
mCurrentPage < getChildCount() - 1) {
finalPage = returnToOriginalPage ? mCurrentPage : mCurrentPage + 1;
snapToPageWithVelocity(finalPage, velocityX);
} else {
snapToDestination();
}
} else if (mTouchState == TOUCH_STATE_PREV_PAGE) {
//直接进入前一屏
int nextPage = Math.max(0, mCurrentPage - 1);
if (nextPage != mCurrentPage) {
snapToPage(nextPage);
} else {
snapToDestination();
}
} else if (mTouchState == TOUCH_STATE_NEXT_PAGE) {
//直接进入后一屏
int nextPage = Math.min(getChildCount() - 1, mCurrentPage + 1);
if (nextPage != mCurrentPage) {
snapToPage(nextPage);
} else {
snapToDestination();
}
} else {
onUnhandledTap(ev);
}
mTouchState = TOUCH_STATE_REST;
mActivePointerId = INVALID_POINTER;
releaseVelocityTracker();
break;
case MotionEvent.ACTION_CANCEL:
if (mTouchState == TOUCH_STATE_SCROLLING) {
snapToDestination();
}
mTouchState = TOUCH_STATE_REST;
mActivePointerId = INVALID_POINTER;
releaseVelocityTracker();
break;
case MotionEvent.ACTION_POINTER_UP:
onSecondaryPointerUp(ev);
break;
}
return true;
}
㈧ android 7.0 launcher3 编译报错:
编译过程中报错提示如下:
make: *** No rule to make target `out/target/common/obj/JAVA_LIBRARIES/libprotobuf-Java-2.3.0-nano_intermediates/javalib.jar', needed by `out/target/common/obj/APPS/Launcher3_intermediates/classes-full-debug.jar'. Stop.
原生的SDK居然报错,没办法只能着手分析了。从字面分析来看是编译需要的protobuf jar包没有build进去导致的,先看看是哪个相关的包。
host-libprotobuf-java-2.3.0-nano.jar这个jar包没编译出来,看了下源码的mk文件,是有相关的编译配置的,于是想想是不是有编译依赖包相关的指令,
网上一找,还真有mma,于是mma一敲,哗啦啦的过了。
网上有很多介绍的文章是在eclips中导入应用进行编译的,此处就不作分析了。回头有空研究下这些个编译指令。。。
㈨ 什么是android launcher开发
Launcher是安卓系统中的桌面启动器,安卓系统的桌面UI统称为Launcher。