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。