Android Launcher3各启动场景源码分析

文章目录

  • 一、概述
  • 二、开机启动Launcher
    • 2.1、开机启动Launcher流程图
    • 2.2、开机启动流程源码分析
  • 三、短压Home键启动Launcher
    • 3.1、短压Home键启动Launcher流程图
    • 3.2、短压Home键启动Launcher源码分析
  • 四、Launcher异常崩溃后的自启动
    • 4.1、Launcher异常崩溃后的自启动流程图
    • 4.2、Launcher异常崩溃后的自启动源码分析


  团队博客: 汽车电子社区


一、概述

  Launcher3是Android系统提供的默认桌面应用(Launcher),它的源码路径在**“packages/apps/Launcher3/”**。Launcher3的启动场景主要包括:
    1、开机后启动:开机时,android ams服务拉起Launcher。
    2、按键启动:比如短压home键,android wms中的PhoneWindowManager拉起Launcher。
    3、异常崩溃后启动:Launcher异常崩溃后,android ams再次拉起Launcher。
  针对这三种情况,分析一下Aosp源码如何实现。

二、开机启动Launcher

2.1、开机启动Launcher流程图

在这里插入图片描述

2.2、开机启动流程源码分析

  Launcher的开机启动由Android的AMS服务完成。AMS在SystemReady阶段会调用startHomeOnAllDisplays函数。Android支持多Display(虚拟Display或者由硬件上报的实际Display),多Display情况下一般Launcher会针对不同Display做不同的效果。

// frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {traceLog.traceBegin("PhaseActivityManagerReady");synchronized(this) {if (mSystemReady) {// If we're done calling all the receivers, run the next "boot phase" passed in// by the SystemServerif (goingCallback != null) {goingCallback.run();}return;}mLocalDeviceIdleController= LocalServices.getService(DeviceIdleController.LocalService.class);mActivityTaskManager.onSystemReady();// Make sure we have the current profile info, since it is needed for security checks.mUserController.onSystemReady();mAppOpsService.systemReady();mSystemReady = true;}try {sTheRealBuildSerial = IDeviceIdentifiersPolicyService.Stub.asInterface(ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE)).getSerial();} catch (RemoteException e) {}ArrayList<ProcessRecord> procsToKill = null;synchronized(mPidsSelfLocked) {for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {ProcessRecord proc = mPidsSelfLocked.valueAt(i);if (!isAllowedWhileBooting(proc.info)){if (procsToKill == null) {procsToKill = new ArrayList<ProcessRecord>();}procsToKill.add(proc);}}}synchronized(this) {if (procsToKill != null) {for (int i=procsToKill.size()-1; i>=0; i--) {ProcessRecord proc = procsToKill.get(i);Slog.i(TAG, "Removing system update proc: " + proc);mProcessList.removeProcessLocked(proc, true, false, "system update done");}}// Now that we have cleaned up any update processes, we// are ready to start launching real processes and know that// we won't trample on them any more.mProcessesReady = true;}Slog.i(TAG, "System now ready");EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, SystemClock.uptimeMillis());mAtmInternal.updateTopComponentForFactoryTest();mAtmInternal.getLaunchObserverRegistry().registerLaunchObserver(mActivityLaunchObserver);watchDeviceProvisioning(mContext);retrieveSettings();mUgmInternal.onSystemReady();final PowerManagerInternal pmi = LocalServices.getService(PowerManagerInternal.class);if (pmi != null) {pmi.registerLowPowerModeObserver(ServiceType.FORCE_BACKGROUND_CHECK,state -> updateForceBackgroundCheck(state.batterySaverEnabled));updateForceBackgroundCheck(pmi.getLowPowerState(ServiceType.FORCE_BACKGROUND_CHECK).batterySaverEnabled);} else {Slog.wtf(TAG, "PowerManagerInternal not found.");}if (goingCallback != null) goingCallback.run();// Check the current user here as a user can be started inside goingCallback.run() from// other system services.final int currentUserId = mUserController.getCurrentUserId();Slog.i(TAG, "Current user:" + currentUserId);if (currentUserId != UserHandle.USER_SYSTEM && !mUserController.isSystemUserStarted()) {// User other than system user has started. Make sure that system user is already// started before switching user.throw new RuntimeException("System user not started while current user is:"+ currentUserId);}traceLog.traceBegin("ActivityManagerStartApps");mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,Integer.toString(currentUserId), currentUserId);mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,Integer.toString(currentUserId), currentUserId);// On Automotive, at this point the system user has already been started and unlocked,// and some of the tasks we do here have already been done. So skip those in that case.// TODO(b/132262830): this workdound shouldn't be necessary once we move the// headless-user start logic to UserManager-landfinal boolean bootingSystemUser = currentUserId == UserHandle.USER_SYSTEM;if (bootingSystemUser) {mSystemServiceManager.startUser(currentUserId);}synchronized (this) {// Only start up encryption-aware persistent apps; once user is// unlocked we'll come back around and start unaware appsstartPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);// Start up initial activity.mBooting = true;// Enable home activity for system user, so that the system can always boot. We don't// do this when the system user is not setup since the setup wizard should be the one// to handle home activity in this case.if (UserManager.isSplitSystemUser() &&Settings.Secure.getInt(mContext.getContentResolver(),Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) {ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);try {AppGlobals.getPackageManager().setComponentEnabledSetting(cName,PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,UserHandle.USER_SYSTEM);} catch (RemoteException e) {throw e.rethrowAsRuntimeException();}}if (bootingSystemUser) {// 启动Home,也就是LaunchermAtmInternal.startHomeOnAllDisplays(currentUserId, "systemReady");}mAtmInternal.showSystemReadyErrorDialogsIfNeeded();if (bootingSystemUser) {final int callingUid = Binder.getCallingUid();final int callingPid = Binder.getCallingPid();long ident = Binder.clearCallingIdentity();try {Intent intent = new Intent(Intent.ACTION_USER_STARTED);intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY| Intent.FLAG_RECEIVER_FOREGROUND);intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);broadcastIntentLocked(null, null, intent,null, null, 0, null, null, null, OP_NONE,null, false, false, MY_PID, SYSTEM_UID, callingUid, callingPid,currentUserId);intent = new Intent(Intent.ACTION_USER_STARTING);intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);broadcastIntentLocked(null, null, intent,null, new IIntentReceiver.Stub() {@Overridepublic void performReceive(Intent intent, int resultCode, String data,Bundle extras, boolean ordered, boolean sticky, int sendingUser)throws RemoteException {}}, 0, null, null,new String[] {INTERACT_ACROSS_USERS}, OP_NONE,null, true, false, MY_PID, SYSTEM_UID, callingUid, callingPid,UserHandle.USER_ALL);} catch (Throwable t) {Slog.wtf(TAG, "Failed sending first user broadcasts", t);} finally {Binder.restoreCallingIdentity(ident);}} else {Slog.i(TAG, "Not sending multi-user broadcasts for non-system user "+ currentUserId);}mAtmInternal.resumeTopActivities(false /* scheduleIdle */);if (bootingSystemUser) {mUserController.sendUserSwitchBroadcasts(-1, currentUserId);}BinderInternal.nSetBinderProxyCountWatermarks(BINDER_PROXY_HIGH_WATERMARK,BINDER_PROXY_LOW_WATERMARK);BinderInternal.nSetBinderProxyCountEnabled(true);BinderInternal.setBinderProxyCountCallback(new BinderInternal.BinderProxyLimitListener() {@Overridepublic void onLimitReached(int uid) {Slog.wtf(TAG, "Uid " + uid + " sent too many Binders to uid "+ Process.myUid());BinderProxy.dumpProxyDebugInfo();if (uid == Process.SYSTEM_UID) {Slog.i(TAG, "Skipping kill (uid is SYSTEM)");} else {killUid(UserHandle.getAppId(uid), UserHandle.getUserId(uid),"Too many Binders sent to SYSTEM");}}}, mHandler);traceLog.traceEnd(); // ActivityManagerStartAppstraceLog.traceEnd(); // PhaseActivityManagerReady}
}

  调用ActivityTaskManagerInternal类型的接口startHomeOnAllDisplays,这个接口ActivityTaskManagerService.java文件中实现。

// android/frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
final class LocalService extends ActivityTaskManagerInternal {@Overridepublic boolean startHomeOnAllDisplays(int userId, String reason) {synchronized (mGlobalLock) {// 这个对象是RootActivityContainer类型return mRootActivityContainer.startHomeOnAllDisplays(userId, reason);}}
}

  接下来调用RootActivityContainer的接口startHomeOnAllDisplays,第二个参数reson的值为“systemReady”。

// frameworks/base/services/core/java/com/android/server/wm/RootActivityContainer.java
boolean startHomeOnAllDisplays(int userId, String reason) {boolean homeStarted = false;for (int i = mActivityDisplays.size() - 1; i >= 0; i--) {final int displayId = mActivityDisplays.get(i).mDisplayId;homeStarted |= startHomeOnDisplay(userId, reason, displayId);}return homeStarted;
}

  遍历mActivityDisplays对于所有处于Active状态的Display调用startHomeOnDisplay,在每个Display上都启动Home(Launcher)。

boolean startHomeOnDisplay(int userId, String reason, int displayId) {// allowInstrumenting :false// fromHomeKey : falsereturn startHomeOnDisplay(userId, reason, displayId, false /* allowInstrumenting */,false /* fromHomeKey */);
}boolean startHomeOnDisplay(int userId, String reason, int displayId, boolean allowInstrumenting,boolean fromHomeKey) {// 如果DisplayID是非法的,使用当前处于顶层焦点的 Display// Fallback to top focused display if the displayId is invalid.if (displayId == INVALID_DISPLAY) {displayId = getTopDisplayFocusedStack().mDisplayId;}// 构建一个IntentIntent homeIntent = null;ActivityInfo aInfo = null;if (displayId == DEFAULT_DISPLAY) {// 如果DisplayID是默认的Display(一般是主屏)// 调用ActivityTaskManagerService的getHomeIntent,拿到用来启动Home的IntenthomeIntent = mService.getHomeIntent();// 查找当前系统里包含 android.intent.category.HOME的Activity。// 择优选择使用哪个ActivityaInfo = resolveHomeActivity(userId, homeIntent);} else if (shouldPlaceSecondaryHomeOnDisplay(displayId)) {// 如果不是默认Display屏幕Pair<ActivityInfo, Intent> info = resolveSecondaryHomeActivity(userId, displayId);aInfo = info.first;homeIntent = info.second;}if (aInfo == null || homeIntent == null) {return false;}// 判断是否运行启动Homeif (!canStartHomeOnDisplay(aInfo, displayId, allowInstrumenting)) {return false;}// 更新Home Intent// Updates the home component of the intent.homeIntent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));homeIntent.setFlags(homeIntent.getFlags() | FLAG_ACTIVITY_NEW_TASK);// 如果是从HomeKey启动的,添加额外参数、// Updates the extra information of the intent.if (fromHomeKey) {homeIntent.putExtra(WindowManagerPolicy.EXTRA_FROM_HOME_KEY, true);}// Update the reason for ANR debugging to verify if the user activity is the one that// actually launched.final String myReason = reason + ":" + userId + ":" + UserHandle.getUserId(aInfo.applicationInfo.uid) + ":" + displayId;// 启动HomemService.getActivityStartController().startHomeActivity(homeIntent, aInfo, myReason,displayId);return true;
}

  startHomeOnDisplay函数中查询当前系统中包含 android.intent.category.HOME信息的Activity(resolveHomeActivity),如果找到了多个Activity则选择高优先级的。根据查找的Activity信息构建Intent,使用ActivityTaskManagerService的ActivityStartController启动Home对应的Activity。
  getHomeIntent函数在ActivityTaskManagerService中实现。

// frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
Intent getHomeIntent() {// String mTopAction = Intent.ACTION_MAIN;Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);intent.setComponent(mTopComponent);intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {// 非FactoryTest模式下走这里。// android.intent.category.HOMEintent.addCategory(Intent.CATEGORY_HOME);}return intent;
}

  resolveHomeActivity函数用于查找包含android.intent.category.HOME信息的Activity。实现上是通过PMS完成的。

// frameworks/base/services/core/java/com/android/server/wm/RootActivityContainer.java
/*** This resolves the home activity info.* @return the home activity info if any.*/
@VisibleForTesting
ActivityInfo resolveHomeActivity(int userId, Intent homeIntent) {final ComponentName comp = homeIntent.getComponent();try {if (comp != null) {// Factory test.} else {final String resolvedType =homeIntent.resolveTypeIfNeeded(mService.mContext.getContentResolver());// 调用PMS查找信息final ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(homeIntent, resolvedType, flags, userId);if (info != null) {aInfo = info.activityInfo;}}} catch (RemoteException e) {// ignore}aInfo = new ActivityInfo(aInfo);aInfo.applicationInfo = mService.getAppInfoForUser(aInfo.applicationInfo, userId);return aInfo;
}

  当找到所需信息后,调用ActivityStartController的startHomeActivity启动Home。该接口与AMS的startActivity和startActivityAsUser实现上基本原理一样,都是通过Intent启动Activity(fork一个进程出来)。

// frameworks/base/services/core/java/com/android/server/wm/ActivityStartController.java
void startHomeActivity(Intent intent, ActivityInfo aInfo, String reason, int displayId) {final ActivityOptions options = ActivityOptions.makeBasic();options.setLaunchWindowingMode(WINDOWING_MODE_FULLSCREEN);if (!ActivityRecord.isResolverActivity(aInfo.name)) {// The resolver activity shouldn't be put in home stack because when the foreground is// standard type activity, the resolver activity should be put on the top of current// foreground instead of bring home stack to front.options.setLaunchActivityType(ACTIVITY_TYPE_HOME);}options.setLaunchDisplayId(displayId);// 启动ActivitymLastHomeActivityStartResult = obtainStarter(intent, "startHomeActivity: " + reason).setOutActivity(tmpOutRecord).setCallingUid(0).setActivityInfo(aInfo).setActivityOptions(options.toBundle()).execute();mLastHomeActivityStartRecord = tmpOutRecord[0];final ActivityDisplay display =mService.mRootActivityContainer.getActivityDisplay(displayId);final ActivityStack homeStack = display != null ? display.getHomeStack() : null;if (homeStack != null && homeStack.mInResumeTopActivity) {// If we are in resume section already, home activity will be initialized, but not// resumed (to avoid recursive resume) and will stay that way until something pokes it// again. We need to schedule another resume.mSupervisor.scheduleResumeTopActivities();}
}

三、短压Home键启动Launcher

3.1、短压Home键启动Launcher流程图

在这里插入图片描述

3.2、短压Home键启动Launcher源码分析

  短压与长按区分,点一下Home键就属于短压。短压Home键后,Android会启动Home。

// frameworks/base/services/core/java/com/android/server/input/InputManagerService.java// Native callback.
private long interceptKeyBeforeDispatching(IBinder focus, KeyEvent event, int policyFlags) {// native层的 inputservice,通过这个接口上报回调return mWindowManagerCallbacks.interceptKeyBeforeDispatching(focus, event, policyFlags);
}
// frameworks/base/services/core/java/com/android/server/wm/InputManagerCallback.java
/**
Provides an opportunity for the window manager policy to process a key before
ordinary dispatch.
*/
@Override
public long interceptKeyBeforeDispatching(IBinder focus, KeyEvent event, int policyFlags) {WindowState windowState = mService.windowForClientLocked(null, focus, false);return mService.mPolicy.interceptKeyBeforeDispatching(windowState, event, policyFlags);
}

  mService是WindowManagerService类型,WindowManagerService中的mPolicy是PhoneWindowManager。PhoneWindowManager作为WMS的Policy配置文件,专门用来处理与UI行为有关的事件。PhoneWindowManager会拦截HomeKey事件进行相应处理后选择不再派发Home(PhoneWindowManager处理完就不需要其他人处理了),或者继续派发HomeKey给当前焦点View。

// frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java
private long interceptKeyBeforeDispatchingInner(WindowState win, KeyEvent event,int policyFlags) {final boolean keyguardOn = keyguardOn();final int keyCode = event.getKeyCode();final int repeatCount = event.getRepeatCount();final int metaState = event.getMetaState();final int flags = event.getFlags();final boolean down = event.getAction() == KeyEvent.ACTION_DOWN;final boolean canceled = event.isCanceled();final int displayId = event.getDisplayId();// First we always handle the home key here, so applications// can never break it, although if keyguard is on, we do let// it handle it, because that gives us the correct 5 second// timeout.if (keyCode == KeyEvent.KEYCODE_HOME) {// 处理HomeKeyDisplayHomeButtonHandler handler = mDisplayHomeButtonHandlers.get(displayId);if (handler == null) {handler = new DisplayHomeButtonHandler(displayId);mDisplayHomeButtonHandlers.put(displayId, handler);}return handler.handleHomeButton(win, event);} else if (keyCode == KeyEvent.KEYCODE_MENU) {// 省略}
}/** A handler to handle home keys per display */
private class DisplayHomeButtonHandler {int handleHomeButton(WindowState win, KeyEvent event) {final boolean keyguardOn = keyguardOn();final int repeatCount = event.getRepeatCount();final boolean down = event.getAction() == KeyEvent.ACTION_DOWN;final boolean canceled = event.isCanceled();// If we have released the home key, and didn't do anything else// while it was pressed, then it is time to go home!if (!down) {// 省略// Post to main thread to avoid blocking input pipeline.// 处理短压HomemHandler.post(() -> handleShortPressOnHome(mDisplayId));return -1;}// 省略return -1;}
}private void handleShortPressOnHome(int displayId) {// Turn on the connected TV and switch HDMI input if we're a HDMI playback device.final HdmiControl hdmiControl = getHdmiControl();if (hdmiControl != null) {hdmiControl.turnOnTv();}// If there's a dream running then use home to escape the dream// but don't actually go home.if (mDreamManagerInternal != null && mDreamManagerInternal.isDreaming()) {mDreamManagerInternal.stopDream(false /*immediate*/);return;}// 启动Home// Go home!launchHomeFromHotKey(displayId);
}

  PhoneWindowManager针对每个Display创建一个DisplayHomeButtonHandler ,通过它处理HomeKey。在启动Home期间如果开始了dream模式(类似于屏保),会先退出dream。最后调用launchHomeFromHotKey来启动Home,后续流程基本上与Home开机启动一致了。

四、Launcher异常崩溃后的自启动

4.1、Launcher异常崩溃后的自启动流程图

在这里插入图片描述

4.2、Launcher异常崩溃后的自启动源码分析

  Launcher意外退出(比如崩溃了)时,会触发AMS的forceStopPackage。AMS会再次将Home拉起。

//frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
@Override
public void forceStopPackage(final String packageName, int userId) {try {IPackageManager pm = AppGlobals.getPackageManager();synchronized(this) {int[] users = userId == UserHandle.USER_ALL? mUserController.getUsers() : new int[] { userId };for (int user : users) {if (mUserController.isUserRunning(user, 0)) {// 对每个运行的User,停掉 packageName对应的应用forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);finishForceStopPackageLocked(packageName, pkgUid);}}}} finally {Binder.restoreCallingIdentity(callingId);}
}

  forceStopPackageLocked函数中,会先Kill掉应用对应的进程。然后 resume focused app,在resume的过程中会拉起Home。

//frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
@GuardedBy("this")
final boolean forceStopPackageLocked(String packageName, int appId,boolean callerWillRestart, boolean purgeCache, boolean doit,boolean evenPersistent, boolean uninstalling, int userId, String reason) {// kill进程boolean didSomething = mProcessList.killPackageProcessesLocked(packageName, appId, userId,ProcessList.INVALID_ADJ, callerWillRestart, true /* allowRestart /, doit,
*                        evenPersistent, true /* setRemoved */,packageName == null ? ("stop user " + userId) : ("stop " + packageName));if (doit) {if (purgeCache && packageName != null) {AttributeCache ac = AttributeCache.instance();if (ac != null) {ac.removePackage(packageName);}}if (mBooted) {// resume focused app// 通过这个函数重新拉起HomemAtmInternal.resumeTopActivities(true /* scheduleIdle */);}}return didSomething;
}

  调用ActivityTaskManagerServiced的resumeTopActivities函数。在 Home崩溃的情况下,调用这个函数,可以保证Home重新被拉起(这个函数最终会调用到RootActivityContainer 的resumeHomeActivity函数。感兴趣的可以继续顺着代码往下看)

//frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@Override
public void resumeTopActivities(boolean scheduleIdle) {synchronized (mGlobalLock) {mRootActivityContainer.resumeFocusedStacksTopActivities();if (scheduleIdle) {mStackSupervisor.scheduleIdleLocked();}}
}
// frameworks/base/services/core/java/com/android/server/wm/RootActivityContainer.java
boolean resumeFocusedStacksTopActivities(ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {// 省略if (!resumedOnDisplay) {// In cases when there are no valid activities (e.g. device just booted or launcher// crashed) it's possible that nothing was resumed on a display. Requesting resume// of top activity in focused stack explicitly will make sure that at least home// activity is started and resumed, and no recursion occurs.final ActivityStack focusedStack = display.getFocusedStack();if (focusedStack != null) {focusedStack.resumeTopActivityUncheckedLocked(target, targetOptions);}}}return result;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/632936.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

OpenGL DIR

Mesa简介-CSDN博客 Mesa, also called Mesa3D and The Mesa 3D Graphics Library, is an open source software implementation of OpenGL, Vulkan, and other graphics API specifications. Mesa translates these specifications to vendor-specific graphics ha…

C++进阶(五)二叉搜索树

&#x1f4d8;北尘_&#xff1a;个人主页 &#x1f30e;个人专栏:《Linux操作系统》《经典算法试题 》《C》 《数据结构与算法》 ☀️走在路上&#xff0c;不忘来时的初心 文章目录 一、二叉搜索树概念二、二叉搜索树操作三、二叉搜索树的实现四、二叉搜索树的应用五、二叉搜索…

mac上搭建 hadoop 伪集群

1. hadoop介绍 Hadoop是Apache基金会开发的一个开源的分布式计算平台&#xff0c;主要用于处理和分析大数据。Hadoop的核心设计理念是将计算任务分布到多个节点上&#xff0c;以实现高度可扩展性和容错性。它主要由以下几个部分组成&#xff1a; HDFS (Hadoop Distributed Fi…

PyTorch各种损失函数解析:深度学习模型优化的关键(1)

目录 详解pytorch中各种Loss functions binary_cross_entropy 用途 用法 参数 数学理论 示例代码 binary_cross_entropy_with_logits 用途 用法 参数 数学理论 示例代码 poisson_nll_loss 用途 用法 参数 数学理论 示例代码 cosine_embedding_loss 用途 …

揭秘程序栈:你的代码在幕后是怎么运行的?

计算机科学中&#xff0c;许多概念和原理可能会让开发者感到头疼&#xff0c;比如程序栈。这个看似晦涩的概念&#xff0c;实对我们理解程序运行至关重要。本文将以通俗易懂的方式&#xff0c;带你深入理解程序栈的工作原理和优化策略。 一、为什么需要栈&#xff1f; 栈是一…

Diffusion Models

DDPM x 0 ∼ q ( x 0 ) x_0 \sim q(x_0) x0​∼q(x0​)是真实数据分布&#xff0c;扩散模型学习一个分布 p θ ( x 0 ) p_\theta(x_0) pθ​(x0​)去逼近真实数据分布。 p θ ( x 0 ) : ∫ p θ ( x 0 : T ) d x 1 : T (1) p_\theta(x_0) : \int p_\theta(x_{0:T})dx_{1:T} \…

chatgpt的实用技巧四temperature 格式

四、temperature 格式 GPT3.5 temperature 的范围为&#xff1a;0-0.7&#xff1b; GPT4.0 temperature 的范围为&#xff1a;0-1&#xff1b; 当 temperature 为 0 时候&#xff0c;结果可稳定。 当 temperature 为 0.7/1 时候&#xff0c;结果发散具备创力。 数值越大&a…

设计模式的学习笔记

设计模式的学习笔记 一. 设计模式相关内容介绍 1 设计模式概述 1.1 软件设计模式的产生背景 设计模式最初并不是出现在软件设计中&#xff0c;而是被用于建筑领域的设计中。 1977 年美国著名建筑大师、加利福尼亚大学伯克利分校环境结构中心主任 Christopher Alexander 在…

【Redis数据类型】String实现及应用场景

文章目录 String1、介绍2、内部实现整数值embstr 编码字符串raw编码字符串 3、常用命令4、应用场景缓存对象常规计数分布式锁共享session信息 参考&#xff1a;小林Coding Redis九种数据类型 Redis 提供了丰富的数据类型&#xff0c;常见的有五种&#xff1a;String&#xff08…

Debian 10.13.0 安装图解

引导和开始安装 这里直接回车确认即可&#xff0c;选择图形化安装方式。 选择语言 这里要区分一下&#xff0c;当前选中的语言作为安装过程中安装器所使用的语言&#xff0c;这里我们选择中文简体。不过细心的同学可能发现&#xff0c;当你选择安装器语言之后&#xff0c;后续安…

电力能源三维可视化合集 | 图扑数字孪生

电力能源是现代社会发展和运行的基石&#xff0c;渗透于工业、商业、农业、家庭生活等方方面面&#xff0c;它为经济、生活质量、环境保护和社会发展提供了巨大的机会和潜力。图扑软件应用自研 HT for Web 强大的渲染引擎&#xff0c;助力现代化的电力能源数字孪生场景&#xf…

运筹说 第95期 | 非线性规划奠基人——库恩与塔克

经过之前的学习&#xff0c;相信大家已经对运筹学的网络计划的内容有了一定的了解&#xff0c;接下来小编将带你学习新一章——非线性规划的内容&#xff0c;让我们先来了解一下非线性规划的诞生和发展历程&#xff0c;然后共同走近非线性规划领域的代表人物——库恩和塔克&…

2.控制语句

1.分支语句/判断语句 if 语句 if(boolean_expression) { /* 如果布尔表达式为真将执行的语句 */ } if…else 语句 if(boolean_expression) { /* 如果布尔表达式为真将执行的语句 / } else { / 如果布尔表达式为假将执行的语句 */ } if…else if…else语句 if(boolean_expressi…

【BERT】详解

BERT 简介 BERT 是谷歌在 2018 年时提出的一种基于 Transformer 的双向编码器的表示学习模型&#xff0c;它在多个 NLP 任务上刷新了记录。它利用了大量的无标注文本进行预训练&#xff0c;预训练任务有掩码语言模型和下一句预测&#xff0c;掩码语言模型指的是随机地替换文本中…

Python基础学习:同步异步阻塞与非阻塞

嗨喽~大家好呀&#xff0c;这里是魔王呐 ❤ ~! python更多源码/资料/解答/教程等 点击此处跳转文末名片免费获取 一、状态介绍 在了解其他概念之前&#xff0c;我们首先要了解进程的几个状态。 在程序运行的过程中&#xff0c;由于被操作系统的调度算法控制&#xff0c;程序…

k8s---pod控制器

pod控制器发的概念&#xff1a; 工作负载&#xff0c;workload用于管理pod的中间层&#xff0c;确保pod资源符合预期的状态。 预期状态&#xff1a; 1、副本数 2、容器重启策略 3、镜像拉取策略 pod出故障的出去等等 pod控制器的类型&#xff1a; 1、replicaset&#xf…

可达性分析

可达性分析 这个算法的基本思路就是通过 一系列称为“GC Roots”的根对象作为起始节点集&#xff0c;从这些节点开始&#xff0c;根据引用关系向下搜索&#xff0c;搜索过 程所走过的路径称为“引用链”&#xff08;Reference Chain&#xff09;&#xff0c;如果某个对象到GC …

力扣22. 括号生成

回溯 思路&#xff1a; 定义函数 dfs(item, open, close, n) 表示当前 item 有左括号个数 open 和右括号个数 close &#xff1b;使用递归&#xff0c;长度为 n 的序列就是在长度为 n - 1 的序列后加左括号或者右括号&#xff1a; 先放左括号&#xff0c;只要其个数 < n&am…

SSL证书自动化管理有什么好处?如何实现SSL证书自动化?

SSL证书是用于加密网站与用户之间传输数据的关键元素&#xff0c;在维护网络安全方面&#xff0c;管理SSL证书与部署SSL证书一样重要。定期更新、监测和更换SSL证书&#xff0c;可以确保网站的安全性和合规性。而自动化管理可以为此节省时间&#xff0c;并避免人为错误和不必要…

微信原生小程序上传与识别以及监听多个checkbox事件打开pdf

1.点击上传并识别 组件样式<van-field border"{{ false }}" placeholder"请输入银行卡卡号" model:value"{{bankNo}}" label"卡号"><van-icon bindtap"handleChooseImg" slot"right-icon" name"sca…