您的位置:首页 > 房产 > 家装 > 重庆建筑工程招聘信息网_网站设计的公司如何选_百度seo查询收录查询_成都seo顾问

重庆建筑工程招聘信息网_网站设计的公司如何选_百度seo查询收录查询_成都seo顾问

2025/5/2 20:23:00 来源:https://blog.csdn.net/ItJavawfc/article/details/147478462  浏览:    关键词:重庆建筑工程招聘信息网_网站设计的公司如何选_百度seo查询收录查询_成都seo顾问
重庆建筑工程招聘信息网_网站设计的公司如何选_百度seo查询收录查询_成都seo顾问

实现Launcher3 桌面屏蔽部分内容,不让显示

文章目录

  • 修改文件路径-实现方式
  • 基础-源码模块配置
    • Launcher3 源码位置
    • 编译模块配置
      • 配置如下参数 属性配置:
        • 默认的Launcher3 选项配置
        • GMS的Launcher3 配置
    • 第三方Launcher需要默认为Launcher时候-系统Launcher3 的配置
  • 参考资料
  • 实现方案
  • 源码分析
    • Launcher
    • LauncherModel
      • addCallbacksAndLoad 方法
      • startLoader
    • LoaderResults
    • BaseLoaderResults
      • bindAllApps
    • AllAppsList
  • 修改实现-举例说明
  • 总结


修改文件路径-实现方式

/vendor/mediatek/proprietary/packages/apps/Launcher3/src/com/android/launcher3/model/AllAppsList.java在copyData 方法中过滤public AppInfo[] copyData() {AppInfo[] result = data.toArray(EMPTY_ARRAY);/* Arrays.sort(result, COMPONENT_KEY_COMPARATOR);return result;*/List<AppInfo> updatedAppInfos = new ArrayList<>();for(AppInfo info:result){if(info.componentName!=null){if(info.componentName.getPackageName().equals("com.android.documentsui")){Log.d(TAG,"info. filter  :"+info.componentName.getPackageName());}else{Log.d(TAG,"info  nofilter:"+info.componentName.getPackageName());updatedAppInfos.add(info);}}}AppInfo[] result1= updatedAppInfos.toArray(new AppInfo[0]);Arrays.sort(result1, COMPONENT_KEY_COMPARATOR);return result1;}

基础-源码模块配置

源码里面的Launcher3 有 非GMS的和GMS的,特别对于MTK、高通、展讯 手机相关平台方案,两个类型Launcher3 模块共存的。 对于 RK 、全志下的大多工控产品下,源码是没有 GMS一说的。

Launcher3 源码位置

MTK 平台 非GMS 源码路径如下:

/vendor/mediatek/proprietary/packages/apps/Launcher3

MTK 平台 GMS包 下

/vendor/google/apps/SearchLauncher
/vendor/google/overlay/gms_overlay/vendor/google/apps/SearchLauncher

在GMS 情况下,为什么会有两个 SearchLauncher, 这是系统的机制而已, gms_overlay 文件夹下的app 包会覆盖非GMS的软件包。

编译模块配置

路径:

\device\mediatek\system\common\device.mk   

配置如下参数 属性配置:

默认的Launcher3 选项配置
#PRODUCT_PACKAGES += Launcher3

如果要使用MTK的GMS 包的 Launcher ,可以配置如下

#PRODUCT_PACKAGES += MtkLauncher3QuickStep

对应的源码位置是如下两个,具体可以查阅下并进行实验:

/vendor/google/apps/SearchLauncher
/vendor/google/overlay/gms_overlay/vendor/google/apps/SearchLauncher

其实这样配置的Launcher3 本身是属于GMS的,所以发现实际跑起来的Launcher是gms包,还带有开机向导。

GMS的Launcher3 配置

GMS 情况下,配置好GMS编译环境即可, 这样就会加载 gms 文件下的所有app 包,里面就有gms 包的Launcher3

\device\mediatek\system\mssi_64_cn\SystemConfig.mk 文件下,配置BUILD_GMS = yes 

第三方Launcher需要默认为Launcher时候-系统Launcher3 的配置

实际工控产品或者消费产品非GMS产品中,客户自定义的Launcher 软件,那么如何配置默认的Launcherne ?
一般有两种解决方案:

  • 系统默认Launcher存在,在源码Framework层默认第三方Launcher为系统Launcher
  • 系统原生Launcher3 也编译到系统里面去,但是去掉Home 属性。
    如下:
    在这里插入图片描述

参考资料

Android11.0内置第三方Launcher并设置为默认,保留Launcher3并可切换
设置三方应用为默认Launcher
动态设置默认Launcher
android 13.0-launcher3中workspaceapp列表页不显示某个app图标
Android13设置默认Launcher分析

其它相关Launcher 资料相关参考:
Launcher3 相关资料参考
菜鸟成长之路-源码分析专栏
Android Launcher3 简介
Launcher3 高端定制
Launcher3 开发
Launcher3 Android Code Search在线源码查看
Launcher3 xref 在线源码查看
Launcher3 RK 源码查看
Launcher3 解析
Launcher3 AndroidP AS版本
谷歌Launcher3 Android13源码修改
Launcher3 和 Launcher3QuickStep 区别
Android14 不分Launcher3修改
Launcher3 LoaderTask 的数据加载
Android14 浅析Launcher
Android O Launcher3-Workspace加载

  • 上面参考资料都是两种Launcher情况下默认其中一个Launcher 作为默认Launcher; 我们上面分析的是保证一个Launcher 即可,系统Launcher 其实去掉了HOME属性。
  • 系统Launcher3 开发,强烈建议多了解下Launcher3 相关的基础知识,数据架子-布局加载-框架相关基本内容,方便分析代码、实现功能,有相关思路。

实现方案

源码分析

Launcher

在onCreate 方法中,有下面这段代码,见名知意 module 相关

   private LauncherModel mModel;@Override@TargetApi(Build.VERSION_CODES.S)protected void onCreate(Bundle savedInstanceState) {...mModel = app.getModel();if (!mModel.addCallbacksAndLoad(this)) {if (!internalStateHandled) {// If we are not binding synchronously, show a fade in animation when// the first page bind completes.mDragLayer.getAlphaProperty(ALPHA_INDEX_LAUNCHER_LOAD).setValue(0);}}...}	

LauncherModel

addCallbacksAndLoad 方法

   /*** Adds a callbacks to receive model updates* @return true if workspace load was performed synchronously*/public boolean addCallbacksAndLoad(Callbacks callbacks) {synchronized (mLock) {addCallbacks(callbacks);return startLoader(new Callbacks[] { callbacks });}}

startLoader

    看这个方法里面的注释:
	    // Enable queue before starting loader. It will get disabled in Launcher#finishBindingItems
 private boolean startLoader(Callbacks[] newCallbacks) {// Enable queue before starting loader. It will get disabled in Launcher#finishBindingItemsItemInstallQueue.INSTANCE.get(mApp.getContext()).pauseModelPush(ItemInstallQueue.FLAG_LOADER_RUNNING);synchronized (mLock) {// If there is already one running, tell it to stop.boolean wasRunning = stopLoader();boolean bindDirectly = mModelLoaded && !mIsLoaderTaskRunning;boolean bindAllCallbacks = wasRunning || !bindDirectly || newCallbacks.length == 0;final Callbacks[] callbacksList = bindAllCallbacks ? getCallbacks() : newCallbacks;if (callbacksList.length > 0) {// Clear any pending bind-runnables from the synchronized load process.for (Callbacks cb : callbacksList) {MAIN_EXECUTOR.execute(cb::clearPendingBinds);}LoaderResults loaderResults = new LoaderResults(mApp, mBgDataModel, mBgAllAppsList, callbacksList);if (bindDirectly) {// Divide the set of loaded items into those that we are binding synchronously,// and everything else that is to be bound normally (asynchronously).loaderResults.bindWorkspace(bindAllCallbacks);// For now, continue posting the binding of AllApps as there are other// issues that arise from that.loaderResults.bindAllApps();loaderResults.bindDeepShortcuts();loaderResults.bindWidgets();return true;} else {stopLoader();// 数据加载 调用工作线程,规避主线程阻塞mLoaderTask = new LoaderTask(mApp, mBgAllAppsList, mBgDataModel, mModelDelegate, loaderResults);// Always post the loader task, instead of running directly// (even on same thread) so that we exit any nested synchronized blocksMODEL_EXECUTOR.post(mLoaderTask);}}}return false;}

这里找到相关的加载App 位置了:

  loaderResults.bindWorkspace(bindAllCallbacks);loaderResults.bindAllApps();loaderResults.bindDeepShortcuts();loaderResults.bindWidgets();

LoaderResults

源码如下: 它是一个中间方法,暂未实质性功能,应该后面方便系统扩展和用户自己扩展了

/*** Helper class to handle results of {@link com.android.launcher3.model.LoaderTask}.*/
public class LoaderResults extends BaseLoaderResults {public LoaderResults(LauncherAppState app, BgDataModel dataModel,AllAppsList allAppsList, Callbacks[] callbacks) {super(app, dataModel, allAppsList, callbacks, MAIN_EXECUTOR);}@Overridepublic void bindDeepShortcuts() {}@Overridepublic void bindWidgets() {}
}

BaseLoaderResults

我们看看这个类的定义:

/*** Stores the list of all applications for the all apps view.*/
public class AllAppsList {

存储app 界面所有应用的集合。

在这里插入图片描述

bindAllApps

   public void bindAllApps() {// shallow copyAppInfo[] apps = mBgAllAppsList.copyData();int flags = mBgAllAppsList.getFlags();executeCallbacksTask(c -> c.bindAllApplications(apps, flags), mUiExecutor);}

这里看到 AppInfo[] apps = mBgAllAppsList.copyData();,下面看到的 bindAllApplications 绑定所有app ,我们最好从顶层来处理拦截 部分不想显示的应用

那就看一下 mBgAllAppsList 在哪里定义的:

    private final AllAppsList mBgAllAppsList;public BaseLoaderResults(LauncherAppState app, BgDataModel dataModel,AllAppsList allAppsList, Callbacks[] callbacksList, LooperExecutor uiExecutor) {。。。。mBgAllAppsList = allAppsList;。。。。}所以继续找到 它的子类,上面我们说了它的子类LoadResults 只是一个中间类,再次贴出它的部分代码:public class LoaderResults extends BaseLoaderResults {public LoaderResults(LauncherAppState app, BgDataModel dataModel,AllAppsList allAppsList, Callbacks[] callbacks) {super(app, dataModel, allAppsList, callbacks, MAIN_EXECUTOR);}那么我们再次回到如上  LauncherModel 的startLoader 方法private boolean startLoader(Callbacks[] newCallbacks) {........................synchronized (mLock) {// If there is already one running, tell it to stop.boolean wasRunning = stopLoader();boolean bindDirectly = mModelLoaded && !mIsLoaderTaskRunning;boolean bindAllCallbacks = wasRunning || !bindDirectly || newCallbacks.length == 0;final Callbacks[] callbacksList = bindAllCallbacks ? getCallbacks() : newCallbacks;if (callbacksList.length > 0) {...............LoaderResults loaderResults = new LoaderResults(mApp, mBgDataModel, mBgAllAppsList, callbacksList);if (bindDirectly) {// Divide the set of loaded items into those that we are binding synchronously,// and everything else that is to be bound normally (asynchronously).loaderResults.bindWorkspace(bindAllCallbacks);// For now, continue posting the binding of AllApps as there are other// issues that arise from that.loaderResults.bindAllApps();loaderResults.bindDeepShortcuts();loaderResults.bindWidgets();return true;} else {stopLoader();// 数据加载 调用工作线程,规避主线程阻塞mLoaderTask = new LoaderTask(mApp, mBgAllAppsList, mBgDataModel, mModelDelegate, loaderResults);// Always post the loader task, instead of running directly// (even on same thread) so that we exit any nested synchronized blocksMODEL_EXECUTOR.post(mLoaderTask);}}}return false;}那就继续追 LoaderResults 构造方法里面的第三个参数  mBgAllAppsList找到变量定义如下:// < only access in worker thread >private final AllAppsList mBgAllAppsList;找到它初始化地方:LauncherModel(Context context, LauncherAppState app, IconCache iconCache, AppFilter appFilter,boolean isPrimaryInstance) {mApp = app;mBgAllAppsList = new AllAppsList(iconCache, appFilter);mModelDelegate = ModelDelegate.newInstance(context, app, mBgAllAppsList, mBgDataModel,isPrimaryInstance);}那么接下来要分析的就是 AllAppsList

AllAppsList

如上在分析 BaseLoaderResults 类的时候 ,已经分析到了 AllAppsList ,然后在bindAllApps 方法里面找到了 mBgAllAppsList.copyData(); ,最后反推到 AllAppsList , 这里需要分析的不就是 如上提到的 copyData嘛。

  public AppInfo[] copyData() {AppInfo[] result = data.toArray(EMPTY_ARRAY);Arrays.sort(result, COMPONENT_KEY_COMPARATOR);return result;}

返回的是AppInfo 数组,那么我们过滤掉 我们不让显示的 App 不就解决了需求了嘛。 先看看 AppInfo
如类注释说明:它代表的就是一个展示在所有AppView 中的一个App . 我们可以通过它的属性类ComponentName 的包名来过滤掉我们想要隐藏的App
在这里插入图片描述

修改实现-举例说明

在第一个内容模块,已经说明了修改路径和修改方法,里面其实已经举例了修改的隐藏文件App
修改前:
在这里插入图片描述
修改之后,编译固件,开机后查看日志如下:说明修改已经起作用了。
在这里插入图片描述
最后看实际界面效果:可以看到文件app 已经被隐藏了,没有显示出来,但是这个app 是安装成功了的。
在这里插入图片描述
去系统设置看看,有木有这个app:看到是有这个app,已经安装过了的。 说明 隐藏成功了…
在这里插入图片描述

总结

  • 这个需求解决方案,完全根据代码找到并进行修改实现,思路还是很清晰的
  • 建议多看看Launcher 相关基础知识,对业务和流程分析非常有好处的。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com