我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Android的SplashScreen是什么

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Android的SplashScreen是什么

本篇内容主要讲解“Android的SplashScreen是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Android的SplashScreen是什么”吧!

什么是SplashScreen

SplashScreen其实通俗点讲就是指的闪屏界面。这个我们国内开发者一定不会陌生,因为绝大多数的国内App都会有闪屏界面这个功能,很多的App还会利用闪屏界面去打广告。下图是QQ的闪屏界面:

Android的SplashScreen是什么

然而在海外,闪屏界面其实并不太常见,甚至Google之前都不推荐我们在App中加入闪屏界面,所以这次Android 12中官方推出了SplashScreen功能还是让我有点意外的。

不过这次官方的SplashScreen和我们国内常见的闪屏界面还不一样,它并不是为了让你在这个界面打广告的,而是为了在App启动初始化的时候避免让用户在一个空白界面等待过长时间。

虽说Android一直是建议我们将重量级的操作延后执行,让App的启动时间越短越好,但是仍然无法完全避免一些App启动时的短暂白屏情况。

因此,这次的SplashScreen就是为了解决这个问题而推出的,它将会在一定程度上提升用户体验,彻底告别过去的启动白屏现象。

Android的SplashScreen是什么

何时会显示SplashScreen

注意,SplashScreen在Android 12上是强制的,即使你什么都不做,你的App在Android 12上也会自动拥有SplashScreen界面。默认情况下,App的Launcher图标会作为SplashScreen界面的中央图标,windowBackground属性指定的颜色会作为SplashScreen界面的背景颜色。不过这些都可以修改。

Android的SplashScreen是什么

关于如何修改我们稍后再谈,既然SplashScreen界面是强制显示的,我们首先应该搞清楚,在什么情况下会显示SplashScreen?

根据官方文档的说明,SplashScreen会在App冷启动和温启动的时候显示,永远不会在App热启动的时候显示。

那么,什么是冷启动、温启动和热启动呢?

简单概括一下的话,如果App被完全杀死了,这个时候去启动它就是冷启动。如果App的主Activity被销毁或回收了,这个时候去启动它就是温启动。如果App只是被挂起到了后台,这个时候去启动它就是热启动。

我这种概括方式在一些细节方面其实并不足够准确,但如果只是为了大概了解SplashScreen的显示时机,那么简单这样理解就可以了。

而如果你想更加细致地学习这几种启动模式的区别,可以参考以下官方文档链接:

https://developer.android.google.cn/topic/performance/vitals/launch-time

何时会隐藏SplashScreen

SplashScreen是为了防止App在冷启动或温启动的时候初始化时间过长,导致用户看到白屏现象而引入的。那么很显然,只要App初始化完成,可以将内容展示给用户的时候,SplashScreen就会自动隐藏。

如果用更加科学一点的定义来描述的话,那就是当App开始在界面上绘制第一帧的时候,SplashScreen就会消失。

那么一个App什么时候会在界面上绘制第一帧呢?我们可以不用知道它准确的时机,但是要知道它大致的时机范围,因为这决定要我们如何更好地编写代码。

假如我们在一个应用的主Activity中编写如下代码:

class MainActivity : AppCompatActivity() {        override fun onCreate(savedInstanceState: Bundle?) {        super.onCreate(savedInstanceState)        setContentView(R.layout.activity_main)        Thread.sleep(3000)    }}

或者也可以这样写:

class MainActivity : AppCompatActivity() {    override fun onCreate(savedInstanceState: Bundle?) {        super.onCreate(savedInstanceState)        setContentView(R.layout.activity_main)    }    override fun onResume() {        super.onResume()        Thread.sleep(3000)    }}

可以看到,我们分别在onCreate()和onResume()方法中让主线程沉睡了3秒钟。然后运行一下程序:

Android的SplashScreen是什么

你会发现,SplashScreen真的显示了3秒钟以上才消失。

同时这也说明了,不管是onCreate()还是onResume()方法,它们都还处于App的初始化阶段,并没有开始在界面上绘制第一帧。

接下来我们可以尝试这样改造一下代码:

class MainActivity : AppCompatActivity() {    override fun onCreate(savedInstanceState: Bundle?) {        super.onCreate(savedInstanceState)        setContentView(R.layout.activity_main)        val contentView: View = findViewById(android.R.id.content)        contentView.post {            Thread.sleep(3000)        }    }}

这里可以借助任何一个View的实例调用一下它的post函数,并在post的回调当中让主线程沉睡3秒。然后再次运行程序:

Android的SplashScreen是什么

你会发现,SplashScreen只是短暂显示了一下就进入了App的主界面。但现在主界面其实还是不能响应任何事件的,而是要等待3秒钟以后才能响应。

由此我们就可以大致得出一些结论,比如说onCreate()和onResume()方法都是在App开始绘制第一帧之前执行的,而View的post回调则是在App绘制第一帧之后执行的。

当第一帧绘制出来以后,说明App的界面上已经可以有东西展示出来了,将不会再是一个空白界面,此时继续展示SplashScreen就没有意义了,所以SplashScreen理应在这个时候消失。但同时,如果在第一帧绘制出来之后我们再在主线程里去执行耗时逻辑,那么用户将会实实在在感受到卡顿的体验,SplashScreen已经无法再帮我们进行掩盖。

实际上,不管是在第一帧绘制之前还是之后,我们都不应该在主线程执行长时间的耗时操作。最正确的做法是,只在主线程里做最少的事情,让App可以快速响应用户的各种输入事件,将所有耗时的逻辑都放到子线程当中去处理。

延长显示SplashScreen

延长SplashScreen的显示时间是一种我不太建议的做法,但我们确实可以这样做。

先说为什么不建议延长SplashScreen的显示时间。

原则上我们应该让App的启动时间越短越好,即使有了SplashScreen,我们也不应该故意让App的启动时间变得更长。

要知道,在SplashScreen的显示过程中,App是一直在主线程里执行初始化操作的。这也就意味着,你的App主线程是一直被占据着的,从而无法响应用户的各种输入,这也就导致了应用程序ANR的可能。不管有没有SplashScreen,只要在主线程里执行了过多耗时操作,都可能会导致ANR。

Android的SplashScreen是什么

那么为什么还要延长显示SplashScreen呢?

有一种说法是,他们App的内容都是从服务器或者从本地磁盘读取的,即使App初始化完成了,数据还没有准备好,也就没有内容可以展示,所以想要将SplashScreen延长到数据准备完成。

但我个人认为这并不是一种非常合适的做法,这种情况我们完全可以先在界面上显示一个加载进度条,或者占位图之类的东西,然后等有了数据之后再更新界面上的内容。

还有一种说法是,他们希望SplashScreen不仅仅是用来加载等待的,还可以用来做一些品牌展示和推广之类的工作。这样如果SplashScreen过快地消失,可能用户根本来不及看到SplashScreen上的内容。

当然,也有另一种说法是,他们在SplashScreen上显示的并不是一个静态的图标,而是一个动画,所以至少要等到动画结束之后再隐藏SplashScreen。

不管你是属于哪一种,Google都给我们提供了延长显示SplashScreen的能力。

刚才说了,SplashScreen会在App开始在界面上绘制第一帧的时候自动消失,那么如果我们阻止了App在界面上绘制第一帧,是不是SplashScreen就不会消失了?

没错,这就是延长显示SplashScreen的工作原理。具体代码如下:

class MainActivity : AppCompatActivity() {        override fun onCreate(savedInstanceState: Bundle?) {        super.onCreate(savedInstanceState)        setContentView(R.layout.activity_main)        val contentView: View = findViewById(android.R.id.content)        contentView.viewTreeObserver.addOnPreDrawListener(object : ViewTreeObserver.OnPreDrawListener {            override fun onPreDraw(): Boolean {                return false            }        })    }}

这里我们在回调函数onPreDraw()中返回了一个false,也就意味着,我们的PreDraw阶段始终没有准备好。既然PreDraw都还没准备好,App肯定是不会开始绘制第一帧的,那么SplashScreen自然也就不会消失了。

于是上述代码将会实现一个永久显示SplashScreen的效果。

有了这个原理,那么我们就可以根据自己的需求编写一些逻辑了。比如刚才提到的从磁盘读取数据的场景,我们可以一开始在onPreDraw()中函数中返回false,然后开启子线程去读取数据,等到数据读取完成再将返回值改成true即可。示例代码如下:

class MainActivity : AppCompatActivity() {    @Volatile    private var isReady = false        override fun onCreate(savedInstanceState: Bundle?) {        super.onCreate(savedInstanceState)        setContentView(R.layout.activity_main)        val contentView: View = findViewById(android.R.id.content)        contentView.viewTreeObserver.addOnPreDrawListener(object : ViewTreeObserver.OnPreDrawListener {            override fun onPreDraw(): Boolean {                if (isReady) {                    contentView.viewTreeObserver.removeOnPreDrawListener(this)                }                return isReady            }        })        thread {             // Read data from disk            ...            isReady = true        }    }}

注意,在SplashScreen的显示过程中,onPreDraw()函数是以很高的频率在持续刷新的。所以它依然会将主线程阻塞住,导致应用程序无法响应用户的输入事件,直到我们在onPreDraw()函数返回true才会停止刷新。

自定义SplashScreen样式

接下来终于到了可能许多朋友最为关心的部分,自定义SplashScreen的样式。

虽然默认的SplashScreen界面并不难看,对于大多数的App来说可能也已经完全足够了,但是Google仍然给了我们比较高的控制权来自定义SplashScreen的样式。

这里我就将几个比较重要的自定义样式属性来跟大家介绍一下。

刚才有提到过,SplashScreen默认会使用windowBackground属性指定的颜色作为界面的背景颜色。但如果我想要单独给SplashScreen界面指定一个背景色呢?可以在主题文件中定义如下属性:

<item name="android:windowSplashScreenBackground">#CCCCCC</item>

这里我们单独将SplashScreen的背景指定成了浅灰色,效果如下图所示:

Android的SplashScreen是什么

需要注意,这个属性以及接下来要介绍的所有属性都是在Android 12系统上新增的,所以你应该在一个values-v31的专属目录下使用它们。

既然能够自定义SplashScreen的背景色,那么我们是不是也可以自定义SplashScreen上的图标呢?

很难想象为什么要在SplashScreen界面上展示一个和Launcher Icon不同的图标,但Google确实允许我们这么做:

<item name="android:windowSplashScreenAnimatedIcon">@drawable/splash_screen_icon</item>

这里我们给SplashScreen界面指定了一个单独的图标,注意这个图标可以是一张静态的图片,也可以是一个动画资源。由于制作动画比较复杂,不在本文的讨论范围内,所以我们只以静态图片来举例。

我准备了这样一张图,并将它命名为splash_screen_icon.jpg。

Android的SplashScreen是什么

然后运行程序,效果如下图所示:

Android的SplashScreen是什么

你会发现,虽然我提供的图标是正方形的,但最终显示在SplashScreen上的却是一个圆形图片。

由此我们可以得出结论,SplashScreen和Launcher Icon一样,也是同样会受到厂商mask的影响的。它的大致工作原理如下图所示:

Android的SplashScreen是什么

可以看到,这里背景层是一张蓝色的网格图,前景层是一张Android机器人Logo图,然后盖上一层圆形的mask,最终就裁剪出了一张圆形的应用图标。

如果对此还不够了解的话,可以去参考我之前写的一篇文章 Android 8.0系统中的应用图标适配 。

上述例子中我使用的是一张不透明的图片来作为图标,其实我们也可以提供一张有透明度的图片,然后再借助如下属性来控制图标的背景色:

<item name="android:windowSplashScreenIconBackgroundColor">#BB86FC</item>

这样,只要前景图标是有透明度的图片,背景颜色就可以显示出来了,如下图所示:

Android的SplashScreen是什么

最后,如果你希望在SplashScreen上再进行一些品牌方面的推广,还可以通过以下属性来显示你的品牌信息:

<item name="android:windowSplashScreenBrandingImage">@drawable/brand_logo</item>

这里可以传入一张品牌图片,我没能在官网找到Google对这张图片尺寸比例的定义,但如果你随便传入一张图片的话,可能会出现拉伸的情况。

为此,我通过自己做实验,大概总结出了这里应该使用一张2.4:1的图片,最终的效果如下图所示:

Android的SplashScreen是什么

适配旧版SplashScreen

最后,我们再来了解一下,如何才能去适配旧版的SplashScreen。

准确来说,Android官方是没有旧版SplashScreen这一说的,因为SplashScreen是在Android 12中才新增加的功能。

但是,有很多的App早在官方提供API之前,就已经自己实现了SplashScreen功能。正如前面所说,这个功能在国内很常见。

那么接下来问题来了。过去通过自己的方式实现的SplashScreen,和现在官方提供的SplashScreen要如何兼容呢?

这着实是一个问题,主要原因在于,SplashScreen在Android 12上是强制启用的。所以,如果你的代码中还保留着过去自己实现的那一套SplashScreen,在Android 12中就会出现双重SplashScreen的现象。

但如果我们从代码中移除了过去自己实现的SplashScreen,那么在Android 12之前的系统版本就没有SplashScreen功能了。

要如何解决这个问题呢?不要着急,Google在AndroidX中提供了一个向下兼容的SplashScreen库。根据官方的说法,我们只要使用这个库就可以轻松解决旧版SplashScreen的适配问题。

用法很简单,跟着如下步骤走即可。

第一步,修改build.gradle文件,将targetSdkVersion指定到31,并添加如下依赖库:

android {
compileSdkVersion 31
...
}
dependencies {
...
implementation 'androidx.core:core-splashscreen:1.0.0-alpha01'
}

第二步,修改主题文件,如下所示:

<style name="MySplashTheme" parent="Theme.SplashScreen">    <item name="windowSplashScreenBackground">#CCCCCC</item>    <item name="windowSplashScreenAnimatedIcon">@drawable/splash_screen_icon</item>    <item name="postSplashScreenTheme">@style/Theme.SplashTest</item></style>

注意这里的变动至关重要。我们新定义了一个主题,这个主题的名字叫什么都可以,但它一定要继承自Theme.SplashScreen。

然后我们可以使用windowSplashScreenBackground和windowSplashScreenAnimatedIcon这两个属性来分别指定SplashScreen的背景色和中央图标。

不过我比较疑惑的是,我们不能像刚才那样在SplashScreen界面指定图标的背景色和品牌图片,因为这里并没有那两个属性。不知道是不是因为现在库还属性比较早期的阶段,以后或许会加上这些属性。

另外,我们还必须要指定postSplashScreenTheme这个属性,将它的值指定成你的App原来的主题。这样,当SplashScreen结束时,你的主题就能够被复原,从而不会影响到你的App的主题外观。

第三步,修改AndroidManifest.xml文件,应用我们刚刚新定义的主题:

<manifest>   <application android:theme="@style/MySplashTheme">    <!-- or -->        <activity android:theme="@style/MySplashTheme">...

这里视你之前代码的写法来决定是替换application标题里的theme,还是activity标题里的theme。

第四步,在你的启动Activity中加入如下代码:

class MainActivity : AppCompatActivity() {        override fun onCreate(savedInstanceState: Bundle?) {        super.onCreate(savedInstanceState)        installSplashScreen()        setContentView(R.layout.activity_main)        ...    }}

如果你还在使用Java语言的话,那么需要改成如下写法:

public class MainActivity extends AppCompatActivity {    @Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    SplashScreen.installSplashScreen(this);    setContentView(R.layout.activity_main);    ...}    }

注意,installSplashScreen()这句代码一定要加入到setContentView()的前面。

这样,当我们刚刚进入App的时候,就会先显示一个SplashScreen界面,然后当App初始化完成之后,SplashScreen会自动消失,并且主题也会变成原来App的主题样式。

接下来我们只需要把过去自己实现的SplashScreen移除即可,不然的话仍然还是会产生双重SplashScreen的现象。

以上步骤是官方提供的适配旧版SplashScreen的解决方案,但是我按照上述步骤进行了一下实现,最终的测试效果却非常差。

主要问题集中在于旧版Android系统上中央图标不会被mask,而在Android 12上中央图标却会被mask,从而导致新旧系统的SplashScreen界面差别很大,也很难看。

不过毕竟我们现在使用的SplashScreen库还处于alpha阶段,后面发生变动的可能性很大,或许这些问题在正式版出现之后都会被修复。

另外,即使官方的库有问题,我们还是完全有办法去规避它。比如说在代码中进行逻辑判断,如果是Android 12系统就不显示自己的SplashScreen界面,因为系统有默认的SplashScreen。而在Android 12以下的系统,就显示自己的SplashScreen界面。

到此,相信大家对“Android的SplashScreen是什么”有了更深的了解,不妨来实际操作一番吧!这里是编程网网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Android的SplashScreen是什么

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Android的SplashScreen是什么

本篇内容主要讲解“Android的SplashScreen是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Android的SplashScreen是什么”吧!什么是SplashScreenS
2023-06-29

Android的surfaceflinger是什么

SurfaceFlinger是Android系统中的一个重要组件,它负责管理屏幕的渲染和显示。它是一个位于系统服务层的图形合成器,负责将应用程序的图形内容合成,并将其显示在设备的屏幕上。SurfaceFlinger使用Android的图形子
2023-09-27

Android下的EXIF是什么

一.什么是Exif Exif(Exchangeable Image File 可交换图像文件)是一种图象文件格式,它的数据存储与JPEG格式是完全相同的。实际上Exif格式就是在JPEG格式头部插入了数码照片的信息,包括拍 摄时的光圈、快门
2022-06-06

android surfaceflinger是什么

SurfaceFlinger是Android系统中的一个重要组件,它负责显示系统中所有图形界面和应用的绘制和渲染工作。它是Android的图形子系统的一个核心部分,负责管理和操作所有的Surface对象(即屏幕缓冲区)。SurfaceFli
2023-09-29

android rom是什么

Android ROM是指基于Android操作系统的固件或系统镜像。ROM是“Read-Only Memory”的缩写,意味着它的内容无法被用户修改。Android ROM可以包含操作系统的核心文件、应用程序、驱动程序和其他系统组件。用户
2023-08-23

android leakcanary的原理是什么

Android LeakCanary是一个用于检测内存泄漏的开源库。它的原理主要包括以下几个步骤:1. 监测对象的引用关系:LeakCanary会监测应用中所有的对象引用关系,包括Activity、Fragment、View等。它会跟踪对象
2023-09-23

Android opengl的用法是什么

OpenGL是一个跨平台的图形库,用于渲染2D和3D图形。在Android上,使用OpenGL可以创建高性能的图形应用程序,包括游戏、模拟器、虚拟现实应用等。Android中使用OpenGL的一般步骤如下:1. 初始化OpenGL环境:在A
2023-10-07

android arouter的用法是什么

ARouter是一个用于在Android应用中进行页面跳转和参数传递的路由框架。它可以帮助开发者更方便地管理Activity之间的跳转关系,并且支持参数的传递和获取。ARouter的用法如下:配置依赖:在项目的build.gradle文件
android arouter的用法是什么
2024-03-02

android oaid的含义是什么

OAID 是“Android 广告标识符(Android Advertising ID)”的缩写。OAID 是一种类似于苹果设备上的 IDFA(Identifier for Advertisers)的设备标识符,用于在 Android 设备
android oaid的含义是什么
2024-03-15

Android ANR的原理是什么

本篇内容介绍了“Android ANR的原理是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、ANR说明和原因1.1 简介ANR全称:
2023-06-21

android ndk的作用是什么

Android NDK(Native Development Kit)是一个用于开发Android应用程序中使用C、C++或其他本地代码的工具集合。它的作用主要有以下几个方面:1. 提供高性能的本地代码支持:NDK允许开发者使用C、C++等
2023-08-23

android jetpack的用法是什么

Android Jetpack是一套库、工具和指南的集合,旨在帮助开发者更轻松地构建高质量的Android应用程序。它提供了一些常用的组件,可以帮助开发者处理常见的Android开发任务。以下是Android Jetpack的一些用法:1.
2023-10-10

android assets的作用是什么

Android assets的作用是存储应用程序所需的非代码资源文件,如图像、音频、视频、字体等。Assets目录下的文件可以通过AssetManager访问并加载到应用程序中。与res目录下的资源文件不同,assets目录中的文件可以保持
2023-09-16

android intent的作用是什么

Android Intent是Android系统中的一个重要组件,用于实现不同组件之间的通信和交互。它可以用于启动Activity、Service、Broadcast Receiver,以及发送广播和数据传递等。具体来说,Android
2023-10-25

android oaid的作用是什么

Android OAID(Open Anonymous Identification)是一种匿名身份标识技术,用于在Android设备上进行用户身份标识和数据统计。其作用主要包括以下几点:用户身份标识:Android OAID可以为每个用户
android oaid的作用是什么
2024-03-15

linux与android指的是什么

这篇文章主要介绍了linux与android指的是什么的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇linux与android指的是什么文章都会有所收获,下面我们一起来看看吧。li
2023-04-20

android application的作用是什么

Android应用程序的主要作用是在Android设备上提供功能和服务。以下是Android应用程序的一些常见作用:1. 提供娱乐和媒体:Android应用程序可以用于播放音乐、观看视频、玩游戏等娱乐活动。例如,音乐播放器、视频播放器、游戏
2023-08-29

android navigation的用法是什么

Android Navigation是一种用于构建应用程序导航结构的库,它提供了一组工具和组件,可以简化应用程序中的导航和目的地管理。Android Navigation的用法包括以下几个方面:1. 定义目的地:使用Navigation组件
2023-09-23

android viewpager的用法是什么

Android ViewPager是一种用户界面组件,用于在应用程序中显示多个页面,并允许用户通过滑动手势在这些页面之间进行切换。它通常与Fragment结合使用,每个页面对应一个Fragment。使用ViewPager的步骤如下:1. 创
2023-09-29

Android Fragment的用法是什么

Android Fragment是一种可以嵌入到Activity中的可重用模块。它可以被看作是Activity中的一部分,具有自己的生命周期和用户界面。Fragment的用法如下:1. 创建Fragment类:继承自android.supp
2023-09-11

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录