微信号:imooc-com

介绍:慕课网是一个超酷的互联网、IT技术免费学习平台,创新的网络一站式学习、实践体验;服务及时贴心,内容专业、有趣易学。专注服务互联网工程师快速成为技术高手!

Android 9.0 强势来袭,带来了哪些新特性?

2018-08-16 08:35 前沿的


使用Wi-Fi RTT进行室内定位

Android 9增加了对IEEE 802.11mc Wi-Fi协议的平台支持 - 也称为Wi-Fi往返时间(RTT) - 让你可以利用在APP室内定位。

在Android 9的设备上,可以使用 RTT API来测量到附近支持RTT的Wi-Fi 接入点(AP)的距离。设备必须启用位置服务并启用Wi-Fi扫描(在 “设置”>“位置”下),APP必须拥有该 ACCESS_FINE_LOCATION权限。设备无需连接到接入点即可使用RTT。为了保持隐私,只有手机能够确定到接入点的距离; 接入点没有此信息。

如果我们的设备测量到3个或更多接入点的距离,我们可以使用多点定位算法来估算最适合这些测量的设备位置。结果通常在1至2米范围内准确。

通过这种准确性,我可以构建新的功能体验,例如室内导航和细粒度的基于位置的服务。

切屏支持


使用仿真器测试显示切屏效果

Android 9 支持最新的 edge-to-edge的屏幕,其中包含用于摄像头和扬声器的显示切屏。该 DisplayCutout 可让我们找出不应显示内容的非功能区域的位置和形状。要确定这些切口区域的存在和位置,请使用该getDisplayCutout() 方法。

新的 window layout 属性 layoutInDisplayCutoutMode  可提供应用在设备的剪裁周围放置其内容。我们可以将此属性设置为以下值之一:

  • LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT

  • LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES

  • LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER

通知

Android 9  引入了一些通知新功能,所有这些功能都可用于针对API级别28及更高级别的开发人员。

增强的消息体验

从Android 7.0(API级别24)开始,开发者可以添加操作以回复消息或直接从通知中输入其他文本。Android 9通过以下增强功能增强了此功能:


  • 对会话参与者的简化支持: Person 该类用于识别对话中涉及的人员,包括他们的头像和URI。许多其他API,例如addMessage(),现在利用Person该类而不是a CharSequence。该Person班还支持生成器设计模式。

  • 支持图像:Android 9现在可以在手机上的消息通知中显示图像。您可以setData() 在消息上使用 以显示图像。以下代码段演示了如何创建Person包含图像的消息和消息



  • // Create new Person.
    Person sender = new Person()
            .setName(name)
            .setUri(uri)
            .setIcon(
    null)
            .build();
    // Create image message.
    Message message = new Message("Picture", time, sender)
            .setData(
    "image/", imageUri);
    Notification.MessagingStyle style = new Notification.MessagingStyle(getUser())
            .addMessage(
    "Check this out!", 0, sender)
            .addMessage(message);



    // Create new Person.
    Person sender = new Person()
            .setName(name)
            .setUri(uri)
            .setIcon(
    null)
            .build();
    // Create image message.
    Message message = new Message("Picture", time, sender)
            .setData(
    "image/", imageUri);
    Notification.MessagingStyle style = new Notification.MessagingStyle(getUser())
            .addMessage(
    "Check this out!", 0, sender)
            .addMessage(message);

    // Create new Person.
    Person sender = new Person()
            .setName(name)
            .setUri(uri)
            .setIcon(
    null)
            .build();
    // Create image message.
    Message message = new Message("Picture", time, sender)
            .setData(
    "image/", imageUri);
    Notification.MessagingStyle style = new Notification.MessagingStyle(getUser())
            .addMessage(
    "Check this out!", 0, sender)
            .addMessage(message);

    • 将回复保存为草稿:EXTRA_REMOTE_INPUT_DRAFT 当用户无意中关闭消息通知时,您的应用可以检索系统发送的回复。您可以使用此额外功能预先填充应用中的文本字段,以便用户完成回复。

    • 确定对话是否是群组对话:您可以使用setGroupConversation() 有目的地将对话识别为群组或非群组对话。

    • 设置intent的语义操作:该 setSemanticAction() 方法允许您为操作赋予语义含义,例如“标记为已读”,“删除”,“回复”等。

    • SmartReply:Android 9支持您的消息传递应用程序中提供的相同建议回复。用于RemoteInput.setChoices() 向用户提供一系列标准响应。

    渠道设置,广播和免打扰

    Android 8.0引入了通知通道,允许您为要显示的每种通知类型创建用户可自定义的通道。Android 9通过以下更改简化了通知渠道设置:

    • 阻止渠道组:用户现在可以在应用的通知设置中阻止整个频道组。你可以使用该 isBlocked() 方法来识别组被阻止的时间,从而不会发送该组中的通道的任何通知。

      此外,你的应用可以使用新getNotificationChannelGroup() 方法查询当前频道组设置 。

    • 新的广播意图类型:Android系统现在在通知通道和通道组的阻塞状态发生变化时发送广播意图。拥有被阻止的通道或组的应用程序可以监听这些意图并做出相应的反应。有关这些意图操作和附加内容的更多信息,请参阅参考中更新的常量列表 NotificationManager 。有关对广播意图作出反应的信息,请参阅广播

    • NotificationManager.Policy 有三个新的请勿打扰优先级类别:

      • PRIORITY_CATEGORY_ALARMS 优先发出警报。

      • PRIORITY_CATEGORY_MEDIA 优先处理来自媒体源的声音,例如媒体和语音导航。

      • PRIORITY_CATEGORY_SYSTEM 优先考虑系统声音。

    • NotificationManager.Policy 还有七个新的Do-Not-Disturb常量可用于抑制视觉中断:

      • SUPPRESSED_EFFECT_FULL_SCREEN_INTENT 阻止通知启动全屏活动。

      • SUPPRESSED_EFFECT_LIGHTS 阻止通知灯。

      • SUPPRESSED_EFFECT_PEEK 防止通知短暂滑入视图(“偷看”)。

      • SUPPRESSED_EFFECT_STATUS_BAR 阻止通知显示在支持状态栏的设备上的状态栏中。

      • SUPPRESSED_EFFECT_BADGE 阻止支持标记的设备上的徽章。有关更多信息,请参阅 修改通知徽章

      • SUPPRESSED_EFFECT_AMBIENT 阻止支持环境显示的设备上的通知。

      • SUPPRESSED_EFFECT_NOTIFICATION_LIST 阻止通知显示在支持列表视图的设备的列表视图中,例如通知阴影或锁屏。

    多相机支持

    在Android 9的设备上,用户可以同时从两个或多个物理摄像头访问数据流。在具有双前置或双后置摄像头的设备上,可实现使用单个摄像头无法实现的创新功能,例如无缝变焦,散景和立体视觉。API还允许调用或融合的摄像机媒体流,以自动在两个或更多摄像机之间切换。

    相机中的其他改进包括 有助于减少初始捕获期间延迟的其他会话参数,以及允许相机客户端处理各种用例而无需停止和启动相机流的表面共享。我们还添加了基于显示的闪存支持 和访问OIS时间戳的 API,以 实现应用级图像稳定和特效。

    在Android 9中,多摄像头API 支持具有FULL或 LIMITED功能的设备的单色摄像头 。单色输出通过YUV_420_888 Y为灰度,U(Cb)为128,V(Cr)为128 的格式实现 。

    Android 9还支持在支持的设备上支持外部USB / UVC摄像头

    用于drawables和bitmaps的ImageDecoder

    Android 9引入了 ImageDecoder 该类,它提供了一种用于解码图像的现代化方法。使用此类而不是BitmapFactory 和BitmapFactory.Options API。

    ImageDecoder允许new一个 Drawable或一个 Bitmap字节缓冲区,文件或URI。要解码图像,请先createSource() 使用编码图像的来源进行调用 。然后,调用 decodeDrawable() 或decodeBitmap() 通过传递ImageDecoder.Source 对象来创建一个Drawable]或一个Bitmap。要更改默认设置,请传递OnHeaderDecodedListener给 decodeDrawable()decodeBitmap()。 一旦知道,就ImageDecoder调用onHeaderDecoded()图像的默认宽度和高度。如果编码图像是动画GIF或WebP,则decodeDrawable()返回该类Drawable的实例 AnimatedImageDrawable

    我们可以使用不同的方法来设置图像属性:

    • 要将解码图像缩放到精确大小,请将目标尺寸传递到 setTargetSize()。您还可以使用样本大小缩放图像。将样本大小直接传递给 setTargetSampleSize()

    • 要在缩放图像范围内裁剪图像,请调用 setCrop()

    • 要创建可变位图,请true进入 setMutableRequired()

    ImageDecoder还可以为图像添加自定义和复杂的效果,如圆角或圆形蒙版。setPostProcessor() 与PostProcessor 类的实例一起 使用 以达到想要的任何绘图效果。

    动画增强

    Android 9引入了 AnimatedImageDrawable 用于绘制和显示GIF和WebP动画图像的类。AnimatedImageDrawable类似于 AnimatedVectorDrawable 渲染线程驱动动画的方式AnimatedImageDrawable。渲染线程还使用工作线程进行解码,因此解码不会干扰渲染线程上的其他操作。此实现允许您的应用显示动画图像,而无需管理其更新或干扰应用的UI线程上的其他事件。

    一个AnimatedImageDrawable可以利用的实例进行解码 ImageDecoder。以下代码段显示了如何使用ImageDecoder解码你的 AnimatedImageDrawable


    private void decodeImage() throws IOException {

        Drawable decodedAnimation = ImageDecoder.decodeDrawable(
           
    ImageDecoder.createSource(getResources(), R.drawable.my_drawable));

       
    if (decodedAnimation instanceof AnimatedImageDrawable) {
           
    // Prior to start(), the first frame is displayed.
            ((
    AnimatedImageDrawable) decodedAnimation).start();
        }
    }


    ImageDecoder有几种方法可以让你进一步修改图像。例如,您可以使用该 setPostProcessor() 方法修改图像的外观,例如应用圆形蒙版或圆角。

    HDR VP9视频,HEIF图像压缩和媒体API

    Android 9增加了对高动态范围(HDR)VP9配置文件2的内置支持,因此我们现在可以通过YouTube,Play电影和支持HDR的设备上的其他来源播放用户提供支持HDR的电影。

    Android 9增加了对平台的HEIF(heic)图像编码的支持。HEIF静态图像样本在MediaMuxerMediaExtractor类中得到支持HEIF改进了压缩以节省存储和网络数据。借助Android 9设备上的平台支持,您可以轻松地从后端服务器发送和使用HEIF图像。确保您的应用与此数据格式兼容以进行共享和显示后,请在应用中尝试将HEIF作为图像存储格式。您可以使用ImageDecoderBitmapFactory进行jpeg-to-heic转换以从jpeg获取位图,并且可以使用HeifWriter从YUV字节缓冲区,Surface或Bitmap写入HEIF静止图像。

    媒体指标也可从AudioTrackAudioRecordMediaDrm类。

    Android 9为MediaDRM类添加了方法, 以获取指标,HDCP级别,安全级别和会话数,并添加对安全级别和安全停止的更多控制。有关详细信息,请参阅API Diff报告

    在Android 9中,AAudio API包含用于使用, 内容类型输入预设的 AAudioStream属性 。使用这些属性,您可以创建针对VoIP或摄像机应用程序进行调整的流。您还可以设置 SessionID 以将AAudio流与可包含效果的子混合相关联。使用 AudioEffect API控制效果。

    Android 9包含用于DynamicsProcessing的 AudioEffect API 。使用此类,我们可以构建基于通道的音频效果,包括各种类型的多个阶段,包括均衡,多频段压缩和限制器。频带和活动阶段的数量是可配置的,并且大多数参数可以实时控制。

    JobScheduler中的数据成本敏感度

    从Android 9开始,JobScheduler 可以使用运营商提供的网络状态信号来改善网络相关作业的处理。

    JobScheduler可以声明其估计的数据大小,信号预取,并指定详细的网络要求。JobScheduler然后根据网络状态管理工作。例如,当网络发出拥塞信号时, JobScheduler可能会推迟大型网络请求。在未计量的网络上,JobScheduler可以运行预取作业以改善用户体验,例如通过预取标题。

    添加作业时,请务必使用setEstimatedNetworkBytes(), setPrefetch()setRequiredNetwork() 在适当时帮助 JobScheduler正确处理工作。当您的作业执行时,请务必使用Network返回的对象JobParameters.getNetwork()。否则,我们可以将隐式使用设备的默认网络,该网络可能无法满足您的要求,从而导致意外的数据使用。

    Neural Networks 1.1

    Neural Networks API 是在8.1的Android(API级27)引入,以加速在Android装置上的机器学习。Android 9扩展并改进了API,增加了对九个新操作的支持:

    • 元素数学运算:

      • ANEURALNETWORKS_DIV

      • ANEURALNETWORKS_SUB

    • 数组操作:

      • ANEURALNETWORKS_BATCH_TO_SPACE_ND

      • ANEURALNETWORKS_SPACE_TO_BATCH_ND

      • ANEURALNETWORKS_SQUEEZE

      • ANEURALNETWORKS_STRIDED_SLICE

      • ANEURALNETWORKS_TRANSPOSE

      • ANEURALNETWORKS_PAD

      • ANEURALNETWORKS_MEAN

    此外,API还引入了一个新功能, ANeuralNetworksModel_relaxComputationFloat32toFloat16()允许您指定是否以ANEURALNETWORKS_TENSOR_FLOAT32 与IEEE 754 16位浮点格式相同的范围和精度进行计算 。

    自动填充框架

    Android 9引入了多项改进,自动填充服务可以实现这些改进,以在填写表单时进一步增强用户体验。

    加强安全

    Android 9引入了许多安全功能,以下各节总结如下:

    Android设备受保护的确认

    运行Android 9或更高版本的受支持设备使你能够使用Android Protected Confirmation。使用此工作流程时,APP权限会向用户显示提示,要求他们同意权限声明。此声明允许应用程序重申用户希望完成敏感交易,例如付款。

    如果用户接受该协议,则Android Keystore将接收并存储受密钥哈希消息身份验证代码(HMAC)保护的加密签名。在Android Keystore确认消息的有效性后,您的应用程序可以使用trustedConfirmationRequired在可信执行环境(TEE)中生成的密钥来签署用户接受的消息。该签名非常有信心地表明用户已经看到该声明并已同意。

    警告: Android Protected Confirmation不为用户提供安全的信息通道。除Android平台提供的保密外,您的应用不能承担任何保密性保证。特别是,请勿使用此工作流程来显示您通常不会在用户设备上显示的敏感信息。

    统一识别认证对话框

    在Android 9中,系统代表您的应用提供生物识别身份验证对话框。此功能为对话框创建标准化的外观,感觉和位置,使用户更有信心他们对可信赖的生物识别凭据检查器进行身份验证。

    如果您的应用程序用于 FingerprintManager 向用户显示指纹身份验证对话框,请切换为使用BiometricPrompt 。BiometricPrompt依赖于系统来显示身份验证对话框。它还会更改其行为以适应用户选择的生物识别身份验证的类型。

    注意:使用前BiometricPrompt在你的应用程序,你应该先使用 hasSystemFeature() 方法,以确保该设备支持FEATURE_FINGERPRINTFEATURE_IRISFEATURE_FACE。如果设备不支持生物识别身份验证,我们可以使用该createConfirmDeviceCredentialIntent() 方法回退到验证用户的PIN,模式或密码 。

    硬件安全模块

    安装了运行Android 9或更高版本的受支持设备可以使用StrongBox Keymaster,它是驻留在硬件安全模块中的Keymaster HAL的实现。该模块包含以下内容:

    • 它自己的CPU。

    • 安全存储。

    • 一个真正的随机数发生器。

    • 防止程序包篡改和未授权的应用程序侧载的其他机制。

    检查存储在StrongBox Keymaster中的密钥时,系统使用可信执行环境(TEE)确认密钥的完整性。

    保密密钥导入Keystore

    Android 9通过添加使用ASN.1编码的密钥格式将加密密钥安全地导入密钥库的功能,提供了额外的密钥解密安全性。Keymaster然后解密密钥库中的密钥,因此密钥的内容永远不会在设备的主机内存中显示为纯文本。

    注意:仅在Keymaster 4或更高版本附带的设备上支持此功能。

    带钥匙旋转的APK签名方案

    Android 9增加了对APK Signature Scheme v3的支持。该方案可以选择在其签名块中为每个签名证书包含一个旋转校对记录。通过将APK文件的过去签名证书链接到现在签名证书的证书,此功能可以使你的应用程序使用新的签名证书进行签名。

    注意:运行Android 8.1(API级别27)或更低版本的设备不支持更改签名证书。如果你的应用程序minSdkVersion27或更低,请使用旧的签名证书来签署您的应用程序以及新签名。

    允许仅在未锁定设备上进行密钥解密的选项

    Android 9引入了unlockedDeviceRequired标志。此选项确定在允许使用指定密钥解密任何正在传输或存储的数据之前,密钥库是否要求解锁屏幕。这些类型的密钥非常适合加密要存储在磁盘上的敏感数据,例如运行状况或企业数据。该标志为用户提供了更高的保证,即如果手机丢失或被盗,设备被锁定时数据无法解密。

    注意:启用unlockedDeviceRequired标志后,加密和签名验证仍可随时进行。该标志在设备解锁时防止解密数据。

    要在设备锁定时保持密钥不被解密,请通过传递truesetUnlockedDeviceRequired() 方法来启用该标志。完成此步骤后,当用户的屏幕被锁定时,使用此密钥解密或签名数据的任何尝试都将失败。锁定的设备需要PIN,密码,指纹或其他可信因素才能访问

    传统加密支持

    Keymaster 4附带的Android 9设备支持三重数据加密算法或三重DES。如果您的应用程序与需要Triple DES的旧系统互操作,请在加密敏感凭据时使用此类型的密码。



    Android备份

    Android 9增加了与备份和恢复相关的新功能和开发人员选项。

    客户端加密备份

    Android 9增加了对使用客户端密钥加密Android备份的支持。满足以下条件时,将自动启用此支持:


  • 用户已使用Android 9或更高版本启用了备份

  • 用户已为其设备设置了屏幕锁定,需要PIN,图案或密码才能解锁。

  • 启用此隐私措施后,需要设备的PIN,模式或密码才能从用户设备的备份中恢复数据。

    定义备份所需的设备条件

    如果您的应用数据包含敏感信息或偏好设置,Android 9可让您定义应用数据包含在用户备份中的设备条件,例如启用客户端加密或本地设备到设备时转移正在进行中

    无障碍辅助服务

    Android 9引入了辅助功能框架的增强功能,可以更轻松地为您的应用用户提供更好的体验。

    引导语义

    Android 9中添加的属性使我们可以更轻松地定义辅助功能服务(尤其是屏幕阅读器)如何从屏幕的一个部分导航到另一个部分。这些属性可以帮助视障人士快速浏览应用UI中的文本,并允许他们进行选择。

    例如,在购物应用中,屏幕阅读器可以帮助用户直接从一种类型的交易导航到下一种交易,而屏幕阅读器不必阅读类别中的所有项目,然后再转到下一个。

    辅助功能窗格标题

    在Android 8.1(API级别27)及更低版本中,辅助功能服务无法始终确定何时更新屏幕的特定窗格,例如活动将一个片段替换为另一个片段。窗格由逻辑分组的,视觉相关的UI元素组成,其通常包括片段。

    在Android 9中,您可以为这些窗格提供辅助功能窗格标题或可单独标识的标题。如果窗格具有辅助功能窗格标题,则辅助功能服务会在窗格更改时收到更详细的信息。此功能允许服务向用户提供有关UI中更改内容的更详细信息。

    要指定窗格的标题,请使用该 android:accessibilityPaneTitle 属性。开发者还可以使用更新在运行时替换的UI窗格的标题setAccessibilityPaneTitle()。例如,可以为Fragment对象的内容区域提供标题 。

    基于标题的引导

    如果我们的应用显示包含逻辑标题的文本内容,请将 android:accessibilityHeading 属性设置trueView代表这些标题的实例 。通过添加这些标题,我们可以使用辅助功能服务来帮助用户直接从一个标题导航到下一个标题。任何辅助功能服务都可以使用此功能来改善用户的UI导航体验。

    组导航和输出

    屏幕阅读器传统上使用该 android:focusable属性来确定何时应该ViewGroupView对象或对象集合 作为单个单元读取 。这样,用户就可以理解视图在逻辑上彼此相关。

    在Android 8.1及更低版本中,您需要将Viewa中的每个对象 标记ViewGroup为不可聚焦,将ViewGroup自身标记为可聚焦。这种安排导致某些实例View以使键盘导航更加麻烦的方式标记为可聚焦。

    从Android 9开始,您可以使用该 android:screenReaderFocusable 属性代替android:focusable属性,在这种情况下,使View对象可聚焦会产生不良后果。屏幕阅读器将重点放在已设置android:screenReaderFocusable 或设置的所有元素android:focusabletrue

    方便操作

    Android 9增加了对代表用户执行便捷措施的支持:

    • 与工具提示交互

    • 通过辅助功能框架中添加的功能,您可以访问 应用程序UI中的工具提示。使用 getTooltipText() 阅读工具提示的文本,并使用 ACTION_SHOW_TOOLTIP 和ACTION_HIDE_TOOLTIP 指导的情况下,View可以显示或隐藏自己的工具提示。

    • 添加了全局操作

    • Android 9引入了对AccessibilityService 类中另外两个设备操作的支持 。我们自定义的服务可以帮助用户分别锁定他们的设备并使用GLOBAL_ACTION_LOCK_SCREEN 和GLOBAL_ACTION_TAKE_SCREENSHOT 操作截取屏幕截图 。

    窗口细节更改

    应用程序同时重绘多个窗口时,Android 9可以更轻松地跟踪应用程序窗口的更新。当一个TYPE_WINDOWS_CHANGED 事件发生时,可以使用 getWindowChanges() API来确定如何在Windows已经改变。在多窗口更新期间,每个窗口都会生成自己的一组事件。该getSource() 方法返回与每个事件关联的窗口的根视图。

    如果应用程序已为其 对象定义了辅助功能窗格标题View,则您的服务可以识别应用程序UI的更新时间。当一个TYPE_WINDOW_STATE_CHANGED 事件发生时,使用由返回的类型 getContentChangeTypes() ,以确定如何在窗口发生了变化。例如,框架可以检测窗格何时具有新标题,或者窗格何时消失。

    旋转

    为了消除无意的旋转,我们添加了一种模式,即使设备位置发生变化也会固定当前方向。用户可以在需要时通过按下系统栏中的按钮手动触发旋转。

    在大多数情况下,对应用程序的兼容性影响很小。但是,如果我们的应用程序具有任何自定义旋转行为或使用任何不寻常的屏幕方向设置,则可能会遇到以前未被注意到的问题,此时用户轮换首选项始终设置为纵向。我们建议您在应用的所有关键活动中查看旋转行为,并确保所有屏幕方向设置仍然提供最佳体验。

    文本

    Android 9为平台带来了以下与文本相关的功能:

    • 预计算文本:PrecomputedText通过使您能够提前计算和缓存所需信息, 该类可提高文本呈现性能。它还使您的应用程序可以在主线程上执行文本布局。

    • 放大镜:Magnifier该类是一个平台小部件,提供放大镜API,允许在所有应用程序中获得一致的放大镜功能体验。

    • 智能链接:Android 9增强了 TextClassifier该类,它利用机器学习识别所选文本中的某些实体并建议操作。例如,TextClassifier可以让您的应用检测用户是否选择了电话号码。然后,您的应用可以建议用户使用该号码拨打电话。这些功能TextClassifier 取代了Linkify该类的功能。

    • 文本布局:几种便捷方法和属性使您可以更轻松地实现UI设计。

    DEX文件的ART提前转换

    在运行Android 9或更高版本的设备上,Android运行时(ART)提前编译器通过将应用程序包中的DEX文件转换为更紧凑的表示形式,进一步优化压缩的Dalvik可执行格式(DEX)文件。此更改允许您的应用程序更快地启动并消耗更少的磁盘空间和RAM。

    这种改进特别有利于磁盘I / O速度较慢的低端设备。

    设备上系统日志跟踪

    Android 9允许开发者从设备中记录系统跟踪,然后与开发团队共享这些日志的报告。此报告支持多种格式,包括HTML。

    通过收集这些跟踪,我们可以捕获与应用程序的进程和线程相关的数据,并可查看目前设备的安全状态。




 
慕课网 更多文章 我是怎么把一个项目带崩的 “职业程序员”不必那么“职业” 如影随形的设计模式与现实世界 作为50 岁的开发者,面对被裁的命运,我如何绝地求生? @程序员,面试必懂的套路,看完整个人通透多了
猜您喜欢 在 Linux 中使用日志来排错 2015成都敏捷之旅之幕后花絮[友强是一个好同学] iOS网络请求在Controller退出后是否应该被取消? 云计算下的企业IT运维 专访死马:为什么说Egg.js是企业级Node框架