欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Android launcher3 -- launcher3源码1

程序员文章站 2022-06-30 16:35:42
...

Android launcher3 – launcher3源码1

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

下载launcher3源码

使用Android Studio运行
Android launcher3 -- launcher3源码1|
Android launcher3 -- launcher3源码1

默认布局读取

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

xml布局文件

一般该文件命中都包含default_workspace字符串,只需要查一下
Android launcher3 -- launcher3源码1


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

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基本结构图

Android launcher3 -- launcher3源码1

相关布局参数

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);
    //。。。。。。省略
}