Android 13 Launcher 根本认识(一)

程序员 2024-10-4 15:02:12 118 0 来自 中国
学习条记:
Android 10.0 launcher 启动流程
Android 13 Launcher 根本认识(一)
Android 13 Launcher 数据加载分析(二)
Android 13 Launcher3 数据库及Workspace 的数据加载与绑定(三)
一、Launcher 简介

Launcher 是 Android 体系不可缺少的部分,我们通常称之为 Android 体系的桌面,它在 Android 体系中起偏紧张的作用。

  • Launcher 是 Android 体系的启动器。在 Launcher 中可以启动你想要利用的应用步调。
  • Launcher 也是应用步调的管理器。可用来对应用步调举行根本的管理,好比删除大概展示应用步调。
  • Launcher 更紧张的意义在于它是一个桌面。在 Android 的桌面上,你可以放置各种快捷方式、桌面小部件,也可以通过 Launcher 更换壁纸,使你的桌面更炫更便利更加个性化。
二、Launcher 结构

在 Launcher 中紧张有两大组件:

  • UI组件:桌面(Workspace)、应用步调菜单(Allapps)、快捷启动栏(Hotseat)、搜索和页面指示条、快捷菜单。
  • 桌面组件:应用步调的快捷方式及相干视图实现(DeepShortcuts)、文件夹及相干视图实现、桌面小部件及相干组件(Widgets)。
三、launcher 启动

参考Android体系开机到Launcher启动流程分析、Android 10.0 launcher启动流程。
四、紧张文件和类


  • Launcher.java:launcher中紧张的activity。
  • LoaderTask.java: 可运行用于加载启动器内容的线程:  工作区图标 、小部件 、全部应用步调图标 、应用步调快捷方式。
  • LauncherAppState.java:用于存储全局变量,好比:缓存(各种cache),维护内存数据的类(LauncherModel)。
  • DragLayer.java:launcher layout的rootview。DragLayer实际上也是一个抽象的界面,用来处理拖动和对事件举行开端处理然后按情况分发下去,角色是一个controller。它起首用onInterceptTouchEvent(MotionEvent)来拦截全部的touch事件,如果是长按item拖动的话不把事件传下去,直接交由onTouchEvent()处理,如许就可以实现item的移动了,如果不是拖动item的话就把事件传到目的view,交有目的view的事件处理函数做相应处理。如过有要对事件的特别需求的话可以修改onInterceptTouchEvent(MotionEvent)来实现所必要的功能。
  • DragController.java:为Drag定义的一个接口。包含一个接口,两个方法和两个静态常量。接口为DragListener(包含onDragStart(),onDragEnd()两个函数),onDragStart()是在刚开始拖动的时间被调用,onDragEnd()是在拖动完成时被调用。在launcher中典范的应用是DeleteZone,在长按拖动item时调用onDragStart()表现,在拖动竣事的时间onDragEnd()潜伏。两个函数包罗startDrag()和setDragItemInfo().startDrag()用于在拖动是转达要拖动的item的信息以及拖动的方式,setDragItemInfo()用于转达item的参数信息(包罗位置以及巨细)。两个常量为DRAG_ACTION_MOVE,DRAG_ACTION_COPY来标识拖动的方式,DRAG_ACTION_MOVE为移动,表现在拖动的时间必要删除原来的item,DRAG_ACTION_COPY为复制型的拖动,表现保存被拖动的item。
  • LauncherModel.java:辅助的文件。内里有许多封装的对数据库的操纵。包含几个线程,此中最紧张的是ApplicationsLoader和DesktopItemsLoader。ApplicationsLoader在加载全部应用步调时利用,DesktopItemsLoader在加载workspace的时间利用。其他的函数就是对数据库的封装,好比在删除,替换,添加步调的时间做更新数据库和UI的工作。
  • Workspace.java:抽象的桌面。由N个celllaout构成,从cellLayout更高一级的层面上对事件的处理。
  • LauncherProvider.java:launcher的数据库,内里存储了桌面的item的信息。在创建数据库的时间会loadFavorites(db)方法,loadFavorites()会剖析xml目次下的default_workspace.xml文件,把此中的内容读出来写到数据库中,如许就做到了桌面的预制。
  • CellLayout.java:构成workspace的view,继续自viewgroup,既是一个dragSource,又是一个dropTarget,可以将它内里的item拖出去,也可以容纳拖动过来的item。在workspace_screen内里定了一些它的view参数。
  • ItemInfo.java:对item的抽象,全部范例item的父类,item包含的属性有id(标识item的id),cellX(在横向位置上的位置,从0开始),cellY(在纵向位置上的位置,从0开始) ,spanX(在横向位置上所占的单位格),spanY(在纵向位置上所占的单位格),screen(在workspace的第几屏,从0开始),itemType(item的范例,有widget,search,application等),container(item地点的)。
  • LauncherSettings.java:字符串的定义。数据库项的字符串定义,别的在这里定义了container的范例,尚有itemType的定义,除此尚有一些特别的widget(如search,clock的定义等)的范例定义。
五、launcher 源码分析

launcher.java 是 launcher 紧张、第一个启动的 activity,在其内里举行表现、初始化一些 View。
launcher#onCreate()
// launcher.java    protected void onCreate(Bundle savedInstanceState) {        // 省略部分代码......        Object traceToken = TraceHelper.INSTANCE.beginSection(ON_CREATE_EVT,                TraceHelper.FLAG_UI_EVENT);        if (DEBUG_STRICT_MODE) {            //StrictMode被称为严苛模式,google提供用来举行测试的类            StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()                    .detectDiskReads()                    .detectDiskWrites()                    .detectNetwork()   // or .detectAll() for all detectable problems                    .penaltyLog()                    .build());            StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()                    .detectLeakedSqlLiteObjects()                    .detectLeakedClosableObjects()                    .penaltyLog()                    .penaltyDeath()                    .build());        }        // 省略部分代码......        super.onCreate(savedInstanceState);        // 单例模式,初始化LauncherAppState        LauncherAppState app = LauncherAppState.getInstance(this);        mOldConfig = new Configuration(getResources().getConfiguration());         // 获取LauncherModel实例        mModel = app.getModel();        mRotationHelper = new RotationHelper(this);        InvariantDeviceProfile idp = app.getInvariantDeviceProfile();        // 初始化手机固件信息对象DeviceProfile        initDeviceProfile(idp);        idp.addOnChangeListener(this);        // 获取sharedPreferences        mSharedPrefs = Utilities.getPrefs(this);        // 获取IconCache实例,此类紧张生存图标信息        mIconCache = app.getIconCache();        mAccessibilityDelegate = createAccessibilityDelegate();        // 拖拽        mDragController = new LauncherDragController(this);        mAllAppsController = new AllAppsTransitionController(this);        mStateManager = new StateManager<>(this, NORMAL);        mOnboardingPrefs = createOnboardingPrefs(mSharedPrefs);        // 获取AppWidgetManager实例,用来管理widge        mAppWidgetManager = new WidgetManagerHelper(this);        mAppWidgetHost = createAppWidgetHost();        mAppWidgetHost.startListening();        // 设置结构        inflateRootView(R.layout.launcher);        // 初始化View,举行各种View的初始化事件绑定        setupViews();        crossFadeWithPreviousAppearance();        mPopupDataProvider = new PopupDataProvider(this::updateNotificationDots);        boolean internalStateHandled = ACTIVITY_TRACKER.handleCreate(this);        // 对于状态举行判断,我们不必要举行任何的设置        if (internalStateHandled) {            if (savedInstanceState != null) {                // InternalStateHandler has already set the appropriate state.                // We dont need to do anything.                savedInstanceState.remove(RUNTIME_STATE);            }        }        restoreState(savedInstanceState);        mStateManager.reapplyState();        if (savedInstanceState != null) {            int[] pageIds = savedInstanceState.getIntArray(RUNTIME_STATE_CURRENT_SCREEN_IDS);            if (pageIds != null) {                mPagesToBindSynchronously = IntSet.wrap(pageIds);            }        }        // 加载、绑定命据(这里与之前版本的 startLoader() 作用一样)        // 如果没有绑定则举行加载、绑定命据        if (!mModel.addCallbacksAndLoad(this)) {            if (!internalStateHandled) {                Log.d(BAD_STATE, "Launcher onCreate not binding sync, prevent drawing");                // If we are not binding synchronously, pause drawing until initial bind complete,                // so that the system could continue to show the device loading prompt                mOnInitialBindListener = Boolean.FALSE::booleanValue;            }        }        // For handling default keys        setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL);        setContentView(getRootView());        if (mOnInitialBindListener != null) {            //getRootView().getViewTreeObserver().addOnPreDrawListener(mOnInitialBindListener);        }        getRootView().dispatchInsets();        // 注册屏幕关闭广播        registerReceiver(mScreenOffReceiver, new IntentFilter(Intent.ACTION_SCREEN_OFF));        getSystemUiController().updateUiState(SystemUiController.UI_STATE_BASE_WINDOW,                Themes.getAttrBoolean(this, R.attr.isWorkspaceDarkText));        if (mLauncherCallbacks != null) {            mLauncherCallbacks.onCreate(savedInstanceState);        }        mOverlayManager = getDefaultOverlay();        PluginManagerWrapper.INSTANCE.get(this).addPluginListener(this,                LauncherOverlayPlugin.class, false /* allowedMultiple */);        mRotationHelper.initialize();        TraceHelper.INSTANCE.endSection(traceToken);        mUserChangedCallbackCloseable = UserCache.INSTANCE.get(this).addUserChangeListener(                () -> getStateManager().goToState(NORMAL));        if (Utilities.ATLEAST_R) {            getWindow().setSoftInputMode(LayoutParams.SOFT_INPUT_ADJUST_NOTHING);        }        setTitle(R.string.home_screen);    }从代码中可以看出,起首调用了 LauncherAppState.getInstance(this) 来初始化一个单例对象 ,而LauncherAppState 内里生存了一些比力常用的对象,方便其他地方通过单例来获取,好比 IconCache、LauncherModel 等;而且注册了广播监听器和 ContentObserver ;设置结构 launcher.xml,调用 setupViews() 又是一些 View 的初始化,设置回调监听等。
总结一下 onCreate() 的工作:初始化对象、加载结构、注册一些事件监听、以及开启数据加载。
您需要登录后才可以回帖 登录 | 立即注册

Powered by CangBaoKu v1.0 小黑屋藏宝库It社区( 冀ICP备14008649号 )

GMT+8, 2024-11-21 21:09, Processed in 0.156339 second(s), 32 queries.© 2003-2025 cbk Team.

快速回复 返回顶部 返回列表