【学以致用】android功能实现10---Launcher8.0启动流程综述

现在网上关于Launcher启动流程的源码分析流传最多的是google Launcher2.0的启动流程。截止2018年5月,google Launcher已经到了8.0版本。

 

经对比,8.0和2.0的启动流程大同小异,整体流程依然保留了2.0的结构特征,以LauncherAppState开始获取手机各项参数,从Launcher到LauncherModel再由LauncherModel到Launcher的回调的合入桌面布局和allapp列表。

 

我个人以代码逻辑和代码量两者结合,将Launcher的oncreate代码分为了7个步骤:

1:创建LauncherAppState 对象,重点是根据手机硬件参数,生成桌面参数。

2:分屏模式的处理

3:统一创建对象

4:生成桌面分布局

5:计算桌面各布局细节参数

6:LauncherModel的布局操作

扫描二维码关注公众号,回复: 2336547 查看本文章

7:横屏和callback

 

以上7步就得到桌面的UI。

如果在配合用户操作机制和后台触发机制就构成了完整的桌面。Launcher的启动机制会绑定用户操作和后台触发,但是不展开讲解具体的内容。

 

通过对Launcher启动流程的分析可以了解到整个Launcher的框架和架构,也能窥豹一斑的体会Launcher的完成面貌。

 

Launcher8.0的oncreate()方法源码如下:

 

@Override
protected void onCreate(Bundle savedInstanceState) {
    if (mLauncherCallbacks != null) {
        mLauncherCallbacks.preOnCreate();
    }

    super.onCreate(savedInstanceState);

//第一步创建LauncherAppState 对象。不同的手机显示的Launcher布局是一样的,但是其中真正显示的每个图标,每个画面的像素点大小是不同的。Launcher需要根据手机的尺寸密度等参数,计算出更多的信息。第一步是将和手机硬件挂钩的参数都获取出来。
    LauncherAppState app = LauncherAppState.getInstance(this);
    mDeviceProfile = app.getInvariantDeviceProfile().getDeviceProfile(this);

 

//第二步,分屏模式也叫做多屏模式,在多屏模式的时候,Launcher的布局有很多的变化。
    if (isInMultiWindowModeCompat()) {
        Display display = getWindowManager().getDefaultDisplay();
        Point mwSize = new Point();
        display.getSize(mwSize);
        mDeviceProfile = mDeviceProfile.getMultiWindowProfile(this, mwSize);
    }

//第三步统一创建对象,Launcher启动时需要用到的对象,在这里统一创建,为后面进行布局的显示进行铺垫。
    mSharedPrefs = Utilities.getPrefs(this);
    mIsSafeModeEnabled = getPackageManager().isSafeMode();
    mModel = app.setLauncher(this);
    mModelWriter = mModel.getWriter(mDeviceProfile.isVerticalBarLayout());
    mIconCache = app.getIconCache();
    mAccessibilityDelegate = new LauncherAccessibilityDelegate(this);
    mDragController = new DragController(this);
    mAllAppsController = new AllAppsTransitionController(this);
  mStateTransitionAnimation=new LauncherStateTransitionAnimation(this, mAllAppsController);
    mAppWidgetManager = AppWidgetManagerCompat.getInstance(this);
    mAppWidgetHost = new LauncherAppWidgetHost(this, APPWIDGET_HOST_ID);
    mAppWidgetHost.startListening();
    mPaused = false;
    mLauncherView = getLayoutInflater().inflate(R.layout.launcher, null);

//第四步生成桌面分布局,将桌面的各个部分都创建对象,绑定一些事件监听器等,这一步基本将桌面的各个UI子模块都定义完成。

    setupViews();

 

//第五步,UI子模块的细节规划,各个模块的大小,真正的尺寸等等。这一步是采用第一步获取的方案,把第四步的模块细节进行完成。
    mDeviceProfile.layout(this, false /* notifyListeners */);
    mExtractedColors = new ExtractedColors();
    loadExtractedColorsAndColorItems();
    mPopupDataProvider = new PopupDataProvider(this);
    ((AccessibilityManager) getSystemService(ACCESSIBILITY_SERVICE))
            .addAccessibilityStateChangeListener(this);

    lockAllApps();
    restoreState(savedInstanceState);
    if (LauncherAppState.PROFILE_STARTUP) {
        Trace.endSection();
    }
    int currentScreen = PagedView.INVALID_RESTORE_PAGE;
    if (savedInstanceState != null) {
        currentScreen = savedInstanceState.getInt(RUNTIME_STATE_CURRENT_SCREEN, currentScreen);
    }

 

//第六步,生成布局。Launcher不是一张图片,因为不同的手机之间有区别。前五步完成不同手机的区别,保证上至平板,下至翻盖机,不同的分辨率下都能够很好的显示。而手机桌面的变化重点是桌面图标布局不一样,手机中安装的软件不一样。第六步就是生成这两种布局。


    if (!mModel.startLoader(currentScreen)) {
        mDragLayer.setAlpha(0);
    } else {
        mWorkspace.setCurrentPage(currentScreen);
        setWorkspaceLoading(true);
    }

//第七步,横屏和CallBack等善后
    mDefaultKeySsb = new SpannableStringBuilder();
    Selection.setSelection(mDefaultKeySsb, 0);

    mRotationEnabled = getResources().getBoolean(R.bool.allow_rotation);
    if (!mRotationEnabled) {
        mRotationEnabled = Utilities.isAllowRotationPrefEnabled(getApplicationContext());
        mRotationPrefChangeHandler = new RotationPrefChangeHandler();
        mSharedPrefs.registerOnSharedPreferenceChangeListener(mRotationPrefChangeHandler);
    }

    if (PinItemDragListener.handleDragRequest(this, getIntent())) {
        mRotationEnabled = true;
    }
    setOrientation();

    setContentView(mLauncherView);
    if (mLauncherCallbacks != null) {
        mLauncherCallbacks.onCreate(savedInstanceState);
    }
}

 

以上是Launcher的启动流程,也是生成桌面的流程。个人认为最重要的两部分,第一部分是第一步和第四步,知道Launcher的整体UI显示框架是怎么来的。 第二部分是第六步,知道桌面的最大特点,自定义图标摆放是怎么读取的。

 

最后关于自定义图标摆放的操作属于Launcher用户操作处理流程,不在启动流程里面。

我在后面会详细分析每一步的操作。

猜你喜欢

转载自blog.csdn.net/dax120/article/details/81172560