Android 12系统源码_SystemUI(六)显示和隐藏最近任务
前言
Android12对最近任务做了调整,将原本处于SystemUI模块的最近任务转移到了Launcher3QuickStep应用中。
本篇文章我们会结合源码一起来梳理一下最近任务的显示流程。
一、SystemUI模块显示最近任务的相关代码
1、在SystemUI模块调用CommandQueue的showRecentApps方法可以实现最近任务的显示。
frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
public class CommandQueue extends IStatusBar.Stub implementsCallbackController<Callbacks>,DisplayManager.DisplayListener {private Handler mHandler = new H(Looper.getMainLooper());public void showRecentApps(boolean triggeredFromAltTab) {synchronized (mLock) {mHandler.removeMessages(MSG_SHOW_RECENT_APPS);mHandler.obtainMessage(MSG_SHOW_RECENT_APPS, triggeredFromAltTab ? 1 : 0, 0,null).sendToTarget();}}}
showRecentApps方法会调用Handler发送类型为MSG_SHOW_RECENT_APPS的消息。
2、Handler对象在接收到MSG_SHOW_RECENT_APPS消息之后,会调用所有回调对象的showRecentApps方法。
public class CommandQueue extends IStatusBar.Stub implementsCallbackController<Callbacks>,DisplayManager.DisplayListener {private static final int MSG_SHOW_RECENT_APPS = 13 << MSG_SHIFT;//显示最近任务private ArrayList<Callbacks> mCallbacks = new ArrayList<>();//回调对象集合private final class H extends Handler {private H(Looper l) {super(l);}public void handleMessage(Message msg) {final int what = msg.what & MSG_MASK;switch (what) {case MSG_SHOW_RECENT_APPS:for (int i = 0; i < mCallbacks.size(); i++) {//调用左右回调对象的showRecentApps方法mCallbacks.get(i).showRecentApps(msg.arg1 != 0);}break;}}}public interface Callbacks {default void showRecentApps(boolean triggeredFromAltTab) {}}}
3、类型为Recents的SystemUI组件实现了CommandQueue.Callbacks接口,并将自身添加到了CommandQueue的监听回调对象集合中,
这样CommandQueue的showRecentApps方法会触发Recents组件的showRecentApps方法。
frameworks/base/packages/SystemUI/src/com/android/systemui/recents/Recents.java
public class Recents extends SystemUI implements CommandQueue.Callbacks {private final RecentsImplementation mImpl;private final CommandQueue mCommandQueue;public Recents(Context context, RecentsImplementation impl, CommandQueue commandQueue) {super(context);mImpl = impl;mCommandQueue = commandQueue;}@Overridepublic void start() {mCommandQueue.addCallback(this);mImpl.onStart(mContext);}//显示最近任务@Overridepublic void showRecentApps(boolean triggeredFromAltTab) {// Ensure the device has been provisioned before allowing the user to interact with// recentsif (!isUserSetup()) {return;}android.util.Log.d("SystemUI.Recents", "showRecentApps: triggeredFromAltTab = " + triggeredFromAltTab);mImpl.showRecentApps(triggeredFromAltTab);}}
Recents的showRecentApps方法会进一步调用RecentsImplementation的showRecentApps方法。
4、RecentsImplementation是一个接口。
frameworks/base/packages/SystemUI/src/com/android/systemui/recents/RecentsImplementation.java
public interface RecentsImplementation {default void onStart(Context context) {}default void onBootCompleted() {}default void onAppTransitionFinished() {}default void onConfigurationChanged(Configuration newConfig) {}default void preloadRecentApps() {}default void cancelPreloadRecentApps() {}default void showRecentApps(boolean triggeredFromAltTab) {}default void hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) {}default void toggleRecentApps() {}default void dump(PrintWriter pw) {}
}
5、在SystemUI模块的具体实现类是OverviewProxyRecentsImpl。
frameworks/base/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyRecentsImpl.java
public class OverviewProxyRecentsImpl implements RecentsImplementation {private final static String TAG = "OverviewProxyRecentsImpl";@Nullableprivate final Lazy<Optional<StatusBar>> mStatusBarOptionalLazy;private Context mContext;private Handler mHandler;private TrustManager mTrustManager;private OverviewProxyService mOverviewProxyService;@SuppressWarnings("OptionalUsedAsFieldOrParameterType")@Injectpublic OverviewProxyRecentsImpl(Lazy<Optional<StatusBar>> statusBarOptionalLazy) {mStatusBarOptionalLazy = statusBarOptionalLazy;}@Overridepublic void onStart(Context context) {mContext = context;mHandler = new Handler();mTrustManager = (TrustManager) context.getSystemService(Context.TRUST_SERVICE);//为OverviewProxyService赋值mOverviewProxyService = Dependency.get(OverviewProxyService.class);}@Overridepublic void showRecentApps(boolean triggeredFromAltTab) {android.util.Log.d("SystemUI.OverviewProxyRecentsImpl", "showRecentApps: triggeredFromAltTab = " + triggeredFromAltTab);//IOverviewProxy是一个aidl,最初是调用OverviewProxyService的getProxy方法进行赋值的IOverviewProxy overviewProxy = mOverviewProxyService.getProxy();if (overviewProxy != null) {try {//继续调用onOverviewShown方法overviewProxy.onOverviewShown(triggeredFromAltTab);return;} catch (RemoteException e) {Log.e(TAG, "Failed to send overview show event to launcher.", e);}} else {// Do nothing}}}
OverviewProxyRecentsImpl的showRecentApps方法会进一步调用代理者IOverviewProxy的onOverviewShown方法,IOverviewProxy是一个aidl。这里调用OverviewProxyService的getProxy方法为overviewProxy赋值。mOverviewProxyService最初是通过Dependency进行赋值的。
6、OverviewProxyService类和getProxy方法相关代码如下所示。
public class OverviewProxyService extends CurrentUserTracker implementsCallbackController<OverviewProxyListener>, NavigationModeController.ModeChangedListener,Dumpable {//唤起Launcher3模块TouchInteractionService的Actionprivate static final String ACTION_QUICKSTEP = "android.intent.action.QUICKSTEP_SERVICE";//唤起Launcher3模块TouchInteractionService的Intentprivate final Intent mQuickStepIntent;//远程IPC通信是实现类private IOverviewProxy mOverviewProxy;private boolean mBound;public OverviewProxyService(Context context, CommandQueue commandQueue,Lazy<NavigationBarController> navBarControllerLazy,Lazy<Optional<StatusBar>> statusBarOptionalLazy,NavigationModeController navModeController,NotificationShadeWindowController statusBarWinController, SysUiState sysUiState,Optional<Pip> pipOptional,Optional<LegacySplitScreen> legacySplitScreenOptional,Optional<SplitScreen> splitScreenOptional,Optional<OneHanded> oneHandedOptional,Optional<RecentTasks> recentTasks,Optional<StartingSurface> startingSurface,BroadcastDispatcher broadcastDispatcher,ShellTransitions shellTransitions,ScreenLifecycle screenLifecycle,SmartspaceTransitionController smartspaceTransitionController,UiEventLogger uiEventLogger,DumpManager dumpManager) {super(broadcastDispatcher);...代码省略...//获取最近任务组件名称mRecentsComponentName = ComponentName.unflattenFromString(context.getString(com.android.internal.R.string.config_recentsComponentName));//创建最近任务Activity的意图对象mQuickStepIntent = new Intent(ACTION_QUICKSTEP).setPackage(mRecentsComponentName.getPackageName());...代码省略...startConnectionToCurrentUser();...代码省略...}//成功绑定服务所返回的ServiceConnection对象private final ServiceConnection mOverviewServiceConnection = new ServiceConnection() {@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {...代码省略...//拿到IOverviewProxy对象,为后续跨进程通信做准备mOverviewProxy = IOverviewProxy.Stub.asInterface(service);...代码省略...}};private void internalConnectToCurrentUser() {...代码省略... Intent launcherServiceIntent = new Intent(ACTION_QUICKSTEP).setPackage(mRecentsComponentName.getPackageName());try {//绑定服务mBound = mContext.bindServiceAsUser(launcherServiceIntent,mOverviewServiceConnection,Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE,UserHandle.of(getCurrentUserId()));} catch (SecurityException e) {Log.e(TAG_OPS, "Unable to bind because of security error", e);}...代码省略...}public IOverviewProxy getProxy() {return mOverviewProxy;} }
对以上代码做个简单总结:
1)为最近任务组件名称mRecentsComponentName赋值。
frameworks/base/core/res/res/values/config.xml
<string name="config_recentsComponentName" translatable="false">com.android.launcher3/com.android.quickstep.RecentsActivity</string>
2)创建最近任务Activity的意图对象mQuickStepIntent
3)创建最近任务服务的意图对象launcherServiceIntent,并进行服务绑定,触发mOverviewServiceConnection的回调方法onServiceConnected,
为类型为远程IPC通信的实现类mOverviewProxy对象赋值。
4)调用的getProxy获得远程通信的实现类
二、Launcher3模块显示最近任务的相关代码
梳理完了SystemUI模块和最近任务相关的代码,我们再来看下Launcher3模块相关的代码。
1、通过上面我们可以知道SystemUI模块启动的时候会启动Launcher3模块的最近任务服务,另外还有提到了最近任务Activity组件, 二者的声明如下所示。
packages/apps/Launcher3/quickstep/AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"package="com.android.launcher3"><application android:backupAgent="com.android.launcher3.LauncherBackupAgent"><service android:name="com.android.quickstep.TouchInteractionService"android:permission="android.permission.STATUS_BAR_SERVICE"android:directBootAware="true"android:exported="true"><intent-filter><action android:name="android.intent.action.QUICKSTEP_SERVICE"/></intent-filter></service><activity android:name="com.android.quickstep.RecentsActivity"android:excludeFromRecents="true"android:launchMode="singleTask"android:clearTaskOnLaunch="true"android:stateNotNeeded="true"android:theme="@style/LauncherTheme"android:screenOrientation="unspecified"android:configChanges="keyboard|keyboardHidden|mcc|mnc|navigation|orientation|screenSize|screenLayout|smallestScreenSize"android:resizeableActivity="true"android:resumeWhilePausing="true"android:taskAffinity=""/></application></manifest>
2、第一节我们讲过要想显示最近任务,需要调用CommandQueue的showRecentApps方法,而该方法最终调用的其实是IOverviewProxy的onOverviewShown。
这里我们具体看一下这个aidl的具体内容。
frameworks/base/packages/SystemUI/shared/src/com/android/systemui/shared/recents/IOverviewProxy.aidl
oneway interface IOverviewProxy {void onActiveNavBarRegionChanges(in Region activeRegion) = 11;void onInitialize(in Bundle params) = 12;/*** Sent when overview button is pressed to toggle show/hide of overview.*/void onOverviewToggle() = 6;/*** 显示最近任务*/void onOverviewShown(boolean triggeredFromAltTab) = 7;/*** Sent when overview is to be hidden.*/void onOverviewHidden(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) = 8;/*** Sent when there was an action on one of the onboarding tips view.* TODO: Move this implementation to SystemUI completely*/void onTip(int actionType, int viewType) = 10;/*** Sent when device assistant changes its default assistant whether it is available or not.*/void onAssistantAvailable(boolean available) = 13;/*** Sent when the assistant changes how visible it is to the user.*/void onAssistantVisibilityChanged(float visibility) = 14;/*** Sent when back is triggered.* TODO: Move this implementation to SystemUI completely*/void onBackAction(boolean completed, int downX, int downY, boolean isButton,boolean gestureSwipeLeft) = 15;/*** Sent when some system ui state changes.*/void onSystemUiStateChanged(int stateFlags) = 16;/*** Sent when the split screen is resized*/void onSplitScreenSecondaryBoundsChanged(in Rect bounds, in Rect insets) = 17;/*** Sent when suggested rotation button could be shown*/void onRotationProposal(int rotation, boolean isValid) = 18;/*** Sent when disable flags change*/void disable(int displayId, int state1, int state2, boolean animate) = 19;/*** Sent when behavior changes. See WindowInsetsController#@Behavior*/void onSystemBarAttributesChanged(int displayId, int behavior) = 20;/*** Sent when screen turned on and ready to use (blocker scrim is hidden)*/void onScreenTurnedOn() = 21;/*** Sent when the desired dark intensity of the nav buttons has changed*/void onNavButtonsDarkIntensityChanged(float darkIntensity) = 22;
}
3、Launcher3模块的最近任务服务TouchInteractionService和onOverviewShown方法相关的代码如下所示。
packages/apps/Launcher3/quickstep/src/com/android/quickstep/TouchInteractionService.java
public class TouchInteractionService extends Serviceimplements ProtoTraceable<LauncherTraceProto.Builder> {private OverviewCommandHelper mOverviewCommandHelper;private final TISBinder mTISBinder = new TISBinder();/*** Local IOverviewProxy implementation with some methods for local components*/public class TISBinder extends IOverviewProxy.Stub {@BinderThread@Overridepublic void onOverviewShown(boolean triggeredFromAltTab) {android.util.Log.d("Launcher3.TouchInteractionService", "onOverviewShown: triggeredFromAltTab = " + triggeredFromAltTab);if (triggeredFromAltTab) {TaskUtils.closeSystemWindowsAsync(CLOSE_SYSTEM_WINDOWS_REASON_RECENTS);mOverviewCommandHelper.addCommand(OverviewCommandHelper.TYPE_SHOW_NEXT_FOCUS);} else {mOverviewCommandHelper.addCommand(OverviewCommandHelper.TYPE_SHOW);}}}@Overridepublic IBinder onBind(Intent intent) {Log.d(TAG, "Touch service connected: user=" + getUserId());return mTISBinder;}
}
TISBinder对象的onOverviewShown方法被SystemUI所触发的时候,会进一步调用OverviewCommandHelper对象的addCommand方法,传入TYPE_SHOW。
4、OverviewCommandHelper和显示最近任务相关的代码如下所示。
public class OverviewCommandHelper {public static final int TYPE_SHOW = 1;//显示public static final int TYPE_SHOW_NEXT_FOCUS = 2;public static final int TYPE_HIDE = 3;//隐藏public static final int TYPE_TOGGLE = 4;//切换public static final int TYPE_HOME = 5;//首页public void addCommand(int type) {CommandInfo cmd = new CommandInfo(type);MAIN_EXECUTOR.execute(() -> addCommand(cmd));}private void addCommand(CommandInfo cmd) {boolean wasEmpty = mPendingCommands.isEmpty();mPendingCommands.add(cmd);if (wasEmpty) {executeNext();}}private void executeNext() {if (mPendingCommands.isEmpty()) {return;}CommandInfo cmd = mPendingCommands.get(0);//层层调用,最终触发executeCommand方法。if (executeCommand(cmd)) {scheduleNextTask(cmd);}}private <T extends StatefulActivity<?>> boolean executeCommand(CommandInfo cmd) {BaseActivityInterface<?, T> activityInterface =mOverviewComponentObserver.getActivityInterface();RecentsView recents = activityInterface.getVisibleRecentsView();if (recents == null) {//如果视图为空,说明最近任务视图不可见if (cmd.type == TYPE_HIDE) {// already hiddenreturn true;}if (cmd.type == TYPE_HOME) {android.util.Log.d("Launcher3.OverviewCommandHelper", "executeCommand cmd.type == TYPE_HOME");mService.startActivity(mOverviewComponentObserver.getHomeIntent());LauncherSplitScreenListener.INSTANCE.getNoCreate().notifySwipingToHome();return true;}} else {//如果视图不为空,说明最近任务视图可见switch (cmd.type) {case TYPE_SHOW:// already visiblereturn true;case TYPE_HIDE: {int currentPage = recents.getNextPage();TaskView tv = (currentPage >= 0 && currentPage < recents.getTaskViewCount())? (TaskView) recents.getPageAt(currentPage): null;return launchTask(recents, tv, cmd);}case TYPE_TOGGLE:return launchTask(recents, getNextTask(recents), cmd);case TYPE_HOME:android.util.Log.d("Launcher3.OverviewCommandHelper", "executeCommand TYPE_HOME");recents.startHome();LauncherSplitScreenListener.INSTANCE.getNoCreate().notifySwipingToHome();return true;}}...代码省略...return false;}}
相关文章:
Android 12系统源码_SystemUI(六)显示和隐藏最近任务
前言 Android12对最近任务做了调整,将原本处于SystemUI模块的最近任务转移到了Launcher3QuickStep应用中。 本篇文章我们会结合源码一起来梳理一下最近任务的显示流程。 一、SystemUI模块显示最近任务的相关代码 1、在SystemUI模块调用CommandQueue的showRecentA…...
Docekr三剑客之 Docekr compose
写在前面 Docker三剑客Docker Compose、Docker Machine、Docker Swarm分别是Docker官方开源的三个项目。有着不同的功能: Docker Compose负责实现对 Docker 容器集群的快速编排Docker Machine负责在多种平台上快速安装 Docker 环境Docker Swarm提供 Docker 容器集…...
企业是否具备等保测评资质在哪里查?怎么查?
为了规范等保相关业务办理流程,确保等保业务顺利办理,保障企业合法权益,政策规定,只有取得等保测评资质机构方可办理等保测评业务。因此很多人在问,企业是否具备等保测评资质在哪里查?怎么查? …...

Spacedesk软件推荐,让你的平板也变成电脑的副屏
我的设备: 电脑:戴尔G15 5511、i7-11800H、Windows 11、RTX3060 平板:荣耀V6、麒麟985、安卓10、分辨率2000*1200(手机也行,我用的平板) 实际使用: 先给放一张实际使用的照片 可以让平板变成电脑的副屏…...

Vue 3.0 组合式API 介绍 【Vue3 从零开始】
提示 在阅读文档之前,你应该已经熟悉了这两个 Vue 基础和创建组件。 在 Vue Mastery 上观看关于组合式 API 的免费视频。 通过创建 Vue 组件,我们可以将接口的可重复部分及其功能提取到可重用的代码段中。仅此一项就可以使我们的应用程序在可维护性和…...
【算法数据结构体系篇class13、14】:贪心算法思想
一、贪心算法概念贪心算法概念:1)最自然智慧的算法2)用一种局部最功利的标准,总是做出在当前看来是最好的选择3)难点在于证明局部最功利的标准可以得到全局最优解4)对于贪心算法的学习主要以增加阅历和经验…...
C++知识点,关键字inline ,String,强制类型转化
🐶博主主页:ᰔᩚ. 一怀明月ꦿ ❤️🔥专栏系列:线性代数,C初学者入门训练 🔥座右铭:“不要等到什么都没有了,才下定决心去做” 🚀🚀🚀大家觉不错…...

MyBatis源码分析(六)MetaObject工具类的使用与源码分析
文章目录一、MetaObject基本使用二、关键类源码分析1、MetaObject的构造方法2、PropertyTokenizer分词器3、BeanWrapper4、MetaClass5、DefaultReflectorFactory6、Reflector7、总结三、MetaObject的getValue源码分析写在后面一、MetaObject基本使用 public class User {priva…...

文献资源最多的文献下载神器,99.99%的文献都可下载
用对工具事半功倍,查找下载文献用对工具能节约大量的时间和精力去做更多的事情。 文献党下载器(wxdown.org),几乎整合了所有文献数据库资源,涵盖各种文献类型,包含全部学科。文献党下载器整合的资源如&…...

工控机ARM工业边缘计算机搭建Node-Red环境
搭建Node-Red环境Node-RED是一个基于Node.js的开源可视化流程编程环境,可以轻松构建自定义应用程序,通过连接简单的节点来完成复杂的任务。Node-RED提供了一种简单的方法,可以快速连接到外部服务,从而实现物联网应用的开发。Node-…...

位图/布隆过滤器/海量数据处理方式
位图 位图的概念 所谓位图,就是用每一位来存放某种状态,适用于海量数据,数据无重复的场景。通常是用来判断某个数据存不存在的。 直接来看问题: 给40亿个不重复的无符号整数,没排过序。给一个无符号整数࿰…...

Tomcat 配置文件数据库密码加密
几年前研究过Tomcat context.xml 中数据库密码改为密文的内容,因为当时在客户云桌面代码没有留备份也没有文章记录,最近项目又提出了这个需求就又重新拾起来学习一下。在网上找了一些资料,自己也大概试了一下,目前功能是实现了。参…...

k8s-Kubernetes集群部署
文章目录前言一、Kubernetes简介与架构1.Kubernetes简介2.kubernetes设计架构二、Kubernetes集群部署1.集群环境初始化2.所有节点安装kubeadm3.拉取集群所需镜像3.集群初始化4.安装flannel网络插件5.扩容节点6.设置kubectl命令补齐前言 一、Kubernetes简介与架构 1.Kubernetes…...

Python数据分析案例19——上市银行财务指标对比
我代码栏目都是针对基础的python数据分析人群,比如想写个本科毕业论文,课程论文,做个简单的案例分析等。过去写的案例可能使用了过多的机器学习和深度学习方法,文科的同学看不懂,可能他们仅仅只想用python做个回归或者…...
Python 中错误 ConnectionError: Max retries exceeded with url
出现错误“ConnectionError: Max retries exceeded with url”有多种原因: 向 request.get() 方法传递了不正确或不完整的 URL。我们正受到 API 的速率限制。requests 无法验证您向其发出请求的网站的 SSL 证书。 确保我们指定了正确且完整的 URL 和路径。 # ⛔️…...

SpringBoot下的Spring框架学习(Tedu)——DAY02
SpringBoot下的Spring框架学习(Tedu)——DAY02 目录SpringBoot下的Spring框架学习(Tedu)——DAY02Spring框架学习1.1 Spring介绍1.2 知识铺垫1.2.1 编辑Dog类1.2.2 编辑Cat类1.2.3 编辑测试类User.java1.2.4 上述代码的总结1.3 面…...
容易混淆的点:C语言中char* a[] 与 char a[] 的区别以及各自的用法
char* a[] 和 char a[] 的区别 char* a[] 和 char a[] 是 C 语言中数组的不同声明方式,二者具有以下区别: char a[] 声明的是一个字符数组,其中存储的是一串字符。此时,a 可以被视为一个指向字符的指针。 char* a[]则声明了一个…...

认识Spring(下)
作者:~小明学编程 文章专栏:Spring框架 格言:热爱编程的,终将被编程所厚爱。 目录 Spring更加高效的读取和存储对象 存储bean对象 五大注解 关于五大类注解 对象的注入 属性注入 构造方法注入 Setter注入 三种注入方式的…...
Educational Codeforces Round 144 (Rated for Div. 2) C - Maximum Set
传送门 题意: 对于一个集合,如果它的任意两个元素都能 有 其中一个能整除另一个,那么它是好的。问在区间[L,R] 中由这个区间某些数内构成的好的集合的最长长度是多少,以及且满足这个长度的好集合有多少个。(懒得想就借…...

学python的第四天---基础(2)
一、三角形类型读入数组并排序的方法nlist(map(float,input().split())) c,b,asorted(n)list_1 list(map(float, input().split())) list_1.sort() list_1.reverse()lengthssorted(map(float,input().split(" ")),reverseTrue)二、动物写法一:d{" &…...

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析
1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具,该工具基于TUN接口实现其功能,利用反向TCP/TLS连接建立一条隐蔽的通信信道,支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式,适应复杂网…...
OpenLayers 可视化之热力图
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 热力图(Heatmap)又叫热点图,是一种通过特殊高亮显示事物密度分布、变化趋势的数据可视化技术。采用颜色的深浅来显示…...
蓝桥杯 2024 15届国赛 A组 儿童节快乐
P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡,轻快的音乐在耳边持续回荡,小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下,六一来了。 今天是六一儿童节,小蓝老师为了让大家在节…...

2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面
代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口(适配服务端返回 Token) export const login async (code, avatar) > {const res await http…...

C++ 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...

零基础设计模式——行为型模式 - 责任链模式
第四部分:行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习!行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想:使多个对象都有机会处…...

ios苹果系统,js 滑动屏幕、锚定无效
现象:window.addEventListener监听touch无效,划不动屏幕,但是代码逻辑都有执行到。 scrollIntoView也无效。 原因:这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作,从而会影响…...
安卓基础(aar)
重新设置java21的环境,临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的: MyApp/ ├── app/ …...
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问(基础概念问题) 1. 请解释Spring框架的核心容器是什么?它在Spring中起到什么作用? Spring框架的核心容器是IoC容器&#…...
MySQL 8.0 事务全面讲解
以下是一个结合两次回答的 MySQL 8.0 事务全面讲解,涵盖了事务的核心概念、操作示例、失败回滚、隔离级别、事务性 DDL 和 XA 事务等内容,并修正了查看隔离级别的命令。 MySQL 8.0 事务全面讲解 一、事务的核心概念(ACID) 事务是…...