Android launcher3 -- launcher3源码1

Posted xhBruce

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android launcher3 -- launcher3源码1相关的知识,希望对你有一定的参考价值。

android launcher3 – launcher3源码1

Launcher3(J 泡在网上的日子)
launcher3源码
Launcher3源码分析系列

下载launcher3源码

使用Android Studio运行
|

默认布局读取

Android launcher – launcher源码修改 2简单提及

xml布局文件

一般该文件命中都包含default_workspace字符串,只需要查一下


default_workspace_XxY.xml 桌面默认布局文件,
dw_phone_hotseat.xml 手机hotseat布局(即底部DOCK区)
dw_tablet_hotseat.xml 平板hotseat布局

dw_phone_hotseat.xml

<favorites xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3">
    <!-- Hotseat (We use the screen as the position of the item in the hotseat) -->
    <!-- Dialer, Messaging, [All Apps], Browser, Camera -->
    <resolve
        launcher:container="-101"
        launcher:screen="0"
        launcher:x="0"
        launcher:y="0" >
        <favorite launcher:uri="#Intent;action=android.intent.action.DIAL;end" />
        <favorite launcher:uri="tel:123" />
        <favorite launcher:uri="#Intent;action=android.intent.action.CALL_BUTTON;end" />
    </resolve>

    <resolve
        launcher:container="-101"
        launcher:screen="1"
        launcher:x="1"
        launcher:y="0" >
        <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_MESSAGING;end" />
        <favorite launcher:uri="sms:" />
        <favorite launcher:uri="smsto:" />
        <favorite launcher:uri="mms:" />
        <favorite launcher:uri="mmsto:" />
    </resolve>

    <!-- All Apps -->

    <resolve
        launcher:container="-101"
        launcher:screen="3"
        launcher:x="3"
        launcher:y="0" >
        <favorite
            launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_BROWSER;end" />
        <favorite launcher:uri="http://www.example.com/" />
    </resolve>

    <resolve
        launcher:container="-101"
        launcher:screen="4"
        launcher:x="4"
        launcher:y="0" >
        <favorite launcher:uri="#Intent;action=android.media.action.STILL_IMAGE_CAMERA;end" />
        <favorite launcher:uri="#Intent;action=android.intent.action.CAMERA_BUTTON;end" />
    </resolve>

</favorites>

default_workspace_4x4.xml

<favorites xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3">

    <!-- Hotseat -->
    <include launcher:workspace="@xml/dw_phone_hotseat" />

    <!-- Bottom row -->
    <resolve
        launcher:screen="0"
        launcher:x="0"
        launcher:y="3" >
        <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_EMAIL;end" />
        <favorite launcher:uri="mailto:" />
    </resolve>

    <resolve
        launcher:screen="0"
        launcher:x="1"
        launcher:y="3" >
        <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_GALLERY;end" />
        <favorite launcher:uri="#Intent;type=images/*;end" />
    </resolve>

    <resolve
        launcher:screen="0"
        launcher:x="3"
        launcher:y="3" >
        <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_MARKET;end" />
        <favorite launcher:uri="market://details?id=com.android.launcher" />
    </resolve>

</favorites>

favorites中可用添加自定义:添加第一个相机,可重复创建;第二个日历

<resolve
    launcher:screen="0"
    launcher:x="2"
    launcher:y="3">
    <favorite launcher:uri="#Intent;action=android.media.action.STILL_IMAGE_CAMERA;end" />
    <favorite launcher:uri="#Intent;action=android.intent.action.CAMERA_BUTTON;end" />
</resolve>

<resolve
    launcher:screen="0"
    launcher:x="0"
    launcher:y="0">
    <favorite
        launcher:className="com.android.calendar.AllInOneActivity"
        launcher:packageName="com.android.calendar" />
</resolve>

xml布局文件读取

从Find in Path搜索的中代码中调用

InvariantDeviceProfile.java中

ArrayList<InvariantDeviceProfile> getPredefinedDeviceProfiles() 
    ArrayList<InvariantDeviceProfile> predefinedDeviceProfiles = new ArrayList<>();
    // width, height, #rows, #columns, #folder rows, #folder columns,
    // iconSize, iconTextSize, #hotseat, #hotseatIconSize, defaultLayoutId.
    predefinedDeviceProfiles.add(new InvariantDeviceProfile("Super Short Stubby",
            255, 300,     2, 3, 2, 3, 3, 48, 13, 3, 48, R.xml.default_workspace_4x4));
    predefinedDeviceProfiles.add(new InvariantDeviceProfile("Shorter Stubby",
            255, 400,     3, 3, 3, 3, 3, 48, 13, 3, 48, R.xml.default_workspace_4x4));
    predefinedDeviceProfiles.add(new InvariantDeviceProfile("Short Stubby",
            275, 420,     3, 4, 3, 4, 4, 48, 13, 5, 48, R.xml.default_workspace_4x4));
    predefinedDeviceProfiles.add(new InvariantDeviceProfile("Stubby",
            255, 450,     3, 4, 3, 4, 4, 48, 13, 5, 48, R.xml.default_workspace_4x4));
    predefinedDeviceProfiles.add(new InvariantDeviceProfile("Nexus S",
            296, 491.33f, 4, 4, 4, 4, 4, 48, 13, 5, 48, R.xml.default_workspace_4x4));
    predefinedDeviceProfiles.add(new InvariantDeviceProfile("Nexus 4",
            335, 567,     4, 4, 4, 4, 4, DEFAULT_ICON_SIZE_DP, 13, 5, 56, R.xml.default_workspace_4x4));
    predefinedDeviceProfiles.add(new InvariantDeviceProfile("Nexus 5",
            359, 567,     4, 4, 4, 4, 4, DEFAULT_ICON_SIZE_DP, 13, 5, 56, R.xml.default_workspace_4x4));
    predefinedDeviceProfiles.add(new InvariantDeviceProfile("Large Phone",
            406, 694,     5, 5, 4, 4, 4, 64, 14.4f,  5, 56, R.xml.default_workspace_5x5));
    // The tablet profile is odd in that the landscape orientation
    // also includes the nav bar on the side
    predefinedDeviceProfiles.add(new InvariantDeviceProfile("Nexus 7",
            575, 904,     5, 6, 4, 5, 4, 72, 14.4f,  7, 60, R.xml.default_workspace_5x6));
    // Larger tablet profiles always have system bars on the top & bottom
    predefinedDeviceProfiles.add(new InvariantDeviceProfile("Nexus 10",
            727, 1207,    5, 6, 4, 5, 4, 76, 14.4f,  7, 64, R.xml.default_workspace_5x6));
    predefinedDeviceProfiles.add(new InvariantDeviceProfile("20-inch Tablet",
            1527, 2527,   7, 7, 6, 6, 4, 100, 20,  7, 72, R.xml.default_workspace_4x4));
    return predefinedDeviceProfiles;
从getPredefinedDeviceProfiles()逆向索冀

Launcher.java:

@Override
protected void onCreate(Bundle savedInstanceState)
LauncherAppState.setApplicationContext(getApplicationContext());
LauncherAppState app = LauncherAppState.getInstance();
mModel.startLoader(mWorkspace.getRestorePage());


LauncherModel.java:异步线程LoaderTas加载图标

public void startLoader(int synchronousBindPage, int loadFlags)
mLoaderTask = new LoaderTask(mApp.getContext(), loadFlags);
mLoaderTask.runBindSynchronousPage(synchronousBindPage);
sWorker.post(mLoaderTask);

private class LoaderTask implements Runnable
public void run()
loadAndBindWorkspace()
loadAndBindAllApps();

loadAndBindWorkspace()
loadWorkspace()
bindWorkspace(-1);

loadAndBindAllApps()
loadAllApps();
updateIconCache();


LauncherProvider.java:

@Override
public boolean onCreate()
LauncherAppState.setLauncherProvider(this);

/**
* Loads the default workspace based on the following priority scheme:
* 1) From the app restrictions
* 2) From a package provided by play store
* 3) From a partner configuration APK, already in the system image
* 4) The default configuration for the particular device
*/
synchronized public void loadDefaultFavoritesIfNecessary()
AutoInstallsLayout loader = createWorkspaceLoaderFromAppRestriction();
loader = getDefaultLayoutParser();
if ((mOpenHelper.loadFavorites(mOpenHelper.getWritableDatabase(), loader) <= 0) && usingExternallyProvidedLayout)
mOpenHelper.loadFavorites(mOpenHelper.getWritableDatabase(), getDefaultLayoutParser());

@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
private AutoInstallsLayout createWorkspaceLoaderFromAppRestriction()
return AutoInstallsLayout.get(ctx, packageName, targetResources, mOpenHelper.mAppWidgetHost, mOpenHelper);

private DefaultLayoutParser getDefaultLayoutParser()

private DefaultLayoutParser getDefaultLayoutParser() 
    int defaultLayout = LauncherAppState.getInstance()
            .getInvariantDeviceProfile().defaultLayoutId;
    return new DefaultLayoutParser(getContext(), mOpenHelper.mAppWidgetHost,
            mOpenHelper, getContext().getResources(), defaultLayout);

LauncherAppState.java:

private LauncherAppState() //单例模式
mInvariantDeviceProfile = new InvariantDeviceProfile(sContext);

public InvariantDeviceProfile getInvariantDeviceProfile()
return mInvariantDeviceProfile;


InvariantDeviceProfile.java:

@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
InvariantDeviceProfile(Context context)
ArrayList closestProfiles = findClosestDeviceProfiles(minWidthDps, minHeightDps, getPredefinedDeviceProfiles());

getPredefinedDeviceProfiles()
predefinedDeviceProfiles.add(new InvariantDeviceProfile(“Super Short Stubby”, 255, 300, 2, 3, 2, 3, 3, 48, 13, 3, 48, R.xml.default_workspace_4x4));

InvariantDeviceProfile(String n, float w, float h, int r, int c, int fr, int fc, int maapc, float is, float its, float hs, float his, int dlId)
defaultLayoutId = dlId;

Launcher3基本结构图

相关布局参数

defaultLayoutId :默认布局ID
numRows \\numColumns :workspace行列
numHotseatIcons :DOCK区个数
hotseatAllAppsRank :DOCK区中间AllApps图标位置
numFolderRows \\numFolderColumns :文件夹行列数
iconSize :图标大小
iconTextSize :workspace图标下文字大小
hotseatIconSize :DOCK区图标大小

config_workspaceDefaultScreen:默认主屏在launcher.xml布局中

@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
InvariantDeviceProfile(Context context) 
    //。。。。。。省略
    ArrayList<InvariantDeviceProfile> closestProfiles =
            findClosestDeviceProfiles(minWidthDps, minHeightDps, getPredefinedDeviceProfiles());
    InvariantDeviceProfile interpolatedDeviceProfileOut =
            invDistWeightedInterpolate(minWidthDps,  minHeightDps, closestProfiles);

    InvariantDeviceProfile closestProfile = closestProfiles.get(0);
    numRows = closestProfile.numRows;
    numColumns = closestProfile.numColumns;
    numHotseatIcons = closestProfile.numHotseatIcons;
    hotseatAllAppsRank = (int) (numHotseatIcons / 2);
    defaultLayoutId = closestProfile.defaultLayoutId;
    numFolderRows = closestProfile.numFolderRows;
    numFolderColumns = closestProfile.numFolderColumns;
    minAllAppsPredictionColumns = closestProfile.minAllAppsPredictionColumns;

    iconSize = interpolatedDeviceProfileOut.iconSize;
    iconBitmapSize = Utilities.pxFromDp(iconSize, dm);
    iconTextSize = interpolatedDeviceProfileOut.iconTextSize;
    hotseatIconSize = interpolatedDeviceProfileOut.hotseatIconSize;
    fillResIconDpi = getLauncherIconDensity(iconBitmapSize);
    //。。。。。。省略

以上是关于Android launcher3 -- launcher3源码1的主要内容,如果未能解决你的问题,请参考以下文章

Android 8.0 隐藏 Launcher3

Android 手势导航(Launcher3 部分)

Android launcher3 开发初始篇

Android Launcher3简介

Android Launcher3简介

Android Launcher3简介