前言

看到这个标题的时候,也许你会认为我写错了,Activity不是只有四种启动模式吗?分别为startard,singleTop,singleTask,singleInstance这四种。

一般来说是四种,但是android12的时候新加入了singleInstancePerTask类型,所以就有5种了。

介绍这五种类型之前,我们先略微介绍一下这五种类型在源码中的定义。

首先,我们先看一下官方注释的位置下,这五种类型的注释在attrs_manifest.xml文件中:

<attr name="launchMode"><!-- The default mode, which will usually create a new instance ofthe activity when it is started, though this behavior may changewith the introduction of other options such as{@link android.content.Intent#FLAG_ACTIVITY_NEW_TASKIntent.FLAG_ACTIVITY_NEW_TASK}. --><enum name="standard" value="0" /><!-- If, when starting the activity, there is already aninstance of the same activity class in the foreground that isinteracting with the user, thenre-use that instance.  This existing instance will receive a call to{@link android.app.Activity#onNewIntent Activity.onNewIntent()} withthe new Intent that is being started. --><enum name="singleTop" value="1" /><!-- If, when starting the activity, there is already a task runningthat starts with this activity, then instead of starting a newinstance the current task is brought to the front.  The existinginstance will receive a call to {@link android.app.Activity#onNewIntentActivity.onNewIntent()}with the new Intent that is being started, and with the{@link android.content.Intent#FLAG_ACTIVITY_BROUGHT_TO_FRONTIntent.FLAG_ACTIVITY_BROUGHT_TO_FRONT} flag set.  This is a supersetof the singleTop mode, where if there is already an instanceof the activity being started at the top of the stack, it willreceive the Intent as described there (without theFLAG_ACTIVITY_BROUGHT_TO_FRONT flag set).  See the<a href="{@docRoot}guide/topics/fundamentals/tasks-and-back-stack.html">Tasks and BackStack</a> document for more details about tasks.--><enum name="singleTask" value="2" /><!-- Only allow one instance of this activity to ever berunning.  This activity gets a unique task with only itself runningin it; if it is ever launched again with the same Intent, then thattask will be brought forward and its{@link android.app.Activity#onNewIntent Activity.onNewIntent()}method called.  If thisactivity tries to start a new activity, that new activity will belaunched in a separate task.  See the<a href="{@docRoot}guide/topics/fundamentals/tasks-and-back-stack.html">Tasks and BackStack</a> document for more details about tasks.--><enum name="singleInstance" value="3" /><!-- The activity can only be running as the root activity of the task, the first activitythat created the task, and therefore there will only be one instance of this activityin a task. In constrast to the {@code singleTask} launch mode, this activity can bestarted in multiple instances in different tasks if the{@code FLAG_ACTIVITY_MULTIPLE_TASK} or {@code FLAG_ACTIVITY_NEW_DOCUMENT} is set.--><enum name="singleInstancePerTask" value="4" /></attr>

其次,在看一下这五种模式在Java文件中的定义,在ActivityInfo类中,如下:

    /*** Constant corresponding to <code>standard</code> in* the {@link android.R.attr#launchMode} attribute./public static final int LAUNCH_MULTIPLE = 0;/** Constant corresponding to <code>singleTop</code> in* the {@link android.R.attr#launchMode} attribute./public static final int LAUNCH_SINGLE_TOP = 1;/** Constant corresponding to <code>singleTask</code> in* the {@link android.R.attr#launchMode} attribute./public static final int LAUNCH_SINGLE_TASK = 2;/** Constant corresponding to <code>singleInstance</code> in* the {@link android.R.attr#launchMode} attribute./public static final int LAUNCH_SINGLE_INSTANCE = 3;/** Constant corresponding to <code>singleInstancePerTask</code> in* the {@link android.R.attr#launchMode} attribute.*/public static final int LAUNCH_SINGLE_INSTANCE_PER_TASK = 4;

接下来,我们就依次讲解这五种类型的定义和作用。

一.standard类型

首先讲解standard类型,这也是一个最基本最常用的一种类型。

官方解释

先看官方注释中的描述:

        <!-- The default mode, which will usually create a new instance ofthe activity when it is started, though this behavior may changewith the introduction of other options such as{@link android.content.Intent#FLAG_ACTIVITY_NEW_TASKIntent.FLAG_ACTIVITY_NEW_TASK}. -->

翻译后:

默认的类型,每次使用时通常创建一个新的活动对象,虽然这样的行为会因为引入其它参数配置而发生改变,比如Intent.FLAG_ACTIVITY_NEW_TASK。

实验验证

我们再来通过实验进行验证,创建三个Activity,分别为Test1Activity,Test2Activity,Test3Activity,如下:

        <activity android:name="com.xt.client.activitys.test.Test1Activity" /><activity android:name="com.xt.client.activitys.test.Test2Activity" /><activity android:name="com.xt.client.activitys.test.Test3Activity" />

然后我们在代码中设置如下跳转顺序:Test1->Test2->Test3->Test1

接下来就是实验,按照上面流程跳转后,使用adb命令捕获当前Activity的栈状态如下:

adb命令:adb shell dumpsys activity activities

      Application tokens in top down Z order:* Task{54bb09b #190 type=standard A=10234:com.xt.client U=0 visible=true visibleRequested=true mode=fullscreen translucent=false sz=4}bounds=[0,0][1080,2340]* ActivityRecord{75f3f53 u0 com.xt.client/.activitys.test.Test1Activity} t190}* ActivityRecord{f91f056 u0 com.xt.client/.activitys.test.Test3Activity} t191}* ActivityRecord{777cf91 u0 com.xt.client/.activitys.test.Test2Activity} t190}* ActivityRecord{83d9d17 u0 com.xt.client/.activitys.test.Test1Activity} t190}

整个流程如下图所示,Test3跳转Test1的时候,会直接在Test3上面入栈一个新的Test1。所以Task中有4条ActivityRecrod,从下往上的顺序为:Test1,Test2,Test3,Test1。

总结:

首先这里我们就不验证添加参数的类型了。

standard类型的启动方式,是不断的往一个Task栈上面添加新的Activity,哪怕有同样的Activity,也会重新创建一个添加到栈里面。

二.singleInstance类型

为什么把singleInstance拿到前面来说呢?因为后面singleTop类型中的验证会涉及到singleInstance类型的知识点,所以就拿到前面提前来讲了。

官方解释

<!-- Only allow one instance of this activity to ever berunning.  This activity gets a unique task with only itself runningin it; if it is ever launched again with the same Intent, then thattask will be brought forward and its{@link android.app.Activity#onNewIntent Activity.onNewIntent()}method called.  If thisactivity tries to start a new activity, that new activity will belaunched in a separate task.  See the<a href="{@docRoot}guide/topics/fundamentals/tasks-and-back-stack.html">Tasks and BackStack</a> document for more details about tasks.-->

翻译后:

只允许一个Activity的实例运行。这个Activity会有唯一的task栈只允许它自身在其中运行,每次被加载的时候都被会把这个栈带到前台,同时会调用Activity的onNewIntent方法进行通知。如果这个Activity尝试去启动一个新的Activity,那么新创建的Activity和当前Activity必须是不同的Task栈。

实验验证

我们仍然是三个Activity,其中Test2Activity设置为singleInstance的模式,

        <activity android:name="com.xt.client.activitys.test.Test1Activity" /><activityandroid:name="com.xt.client.activitys.test.Test2Activity"android:launchMode="singleInstance" /><activity android:name="com.xt.client.activitys.test.Test3Activity" />

设置跳转顺序: Test1->Test2->Test3->Test1->Test2->Test3

执行操作,结果如下,我们可以发现Test2单独占用一个Task

      Application tokens in top down Z order:* Task{40cbc68 #196 type=standard A=10234:com.xt.client U=0 visible=true visibleRequested=true mode=fullscreen translucent=false sz=5}bounds=[0,0][1080,2340]* ActivityRecord{cd9b41f u0 com.xt.client/.activitys.test.Test3Activity} t196}* ActivityRecord{9e73f05 u0 com.xt.client/.activitys.test.Test1Activity} t196}* ActivityRecord{8fcaaee u0 com.xt.client/.activitys.test.Test3Activity} t196}* ActivityRecord{5e3a630 u0 com.xt.client/.activitys.test.Test1Activity} t196}* ActivityRecord{9768990 u0 com.xt.client/.MainActivity} t196}* Task{17dfc90 #197 type=standard A=10234:com.xt.client U=0 visible=false visibleRequested=false mode=fullscreen translucent=true sz=1}bounds=[0,0][1080,2340]* ActivityRecord{e147b53 u0 com.xt.client/.activitys.test.Test2Activity} t197}

我们发现区别于第一种类型,这种类型下会有两个Task栈,这两个Task的taskAffinity是一样的。

Test2启动Test3的时候,流程图如下所示。首先前台任务栈从Task2切换到了Task1,Task1中也增加了一条Test3的Activity记录,此时显示在前台的就是Test3了。

总结:

singleInstance类型的启动方式中,

如果不存在包含目标Activity的栈,则创建一个新的Task,这个Task中是目标Activity所独有的,并且只会创建一次,后续如果在启动其它的Activity,这些新的Acitivty属于其parent的task栈。

如果存在包含目标Activity的栈,则直接把包含目标Activity的Task栈挪到前台进行显示。

三.singleTop类型

singleTop相对于startard多了一个复用的概念,就是说某些场景下,会复用已有的Activity而不是每次都新建。

官方解释

        <!-- If, when starting the activity, there is already aninstance of the same activity class in the foreground that isinteracting with the user, thenre-use that instance.  This existing instance will receive a call to{@link android.app.Activity#onNewIntent Activity.onNewIntent()} withthe new Intent that is being started. -->

翻译后:

在启动Activity的时候,如果前台中存在一个相同Activity类的实例与用户交互,则直接使用这个实例。这个存在的实例在启动的时候会通过onNewIntent方法收到通知。

实验验证

这里为了体现singleTop的作用,我们做一个对比实验。

首先,我们设置Test3为singleInstance模式,其他的都是默认的standard模式。

        <activity android:name="com.xt.client.activitys.test.Test1Activity" /><activity android:name="com.xt.client.activitys.test.Test2Activity" /><activityandroid:name="com.xt.client.activitys.test.Test3Activity"android:launchMode="singleInstance" />

然后设置跳转顺序:Test1->Test2->Test3->Test2

结果如下:

      Application tokens in top down Z order:* Task{54bb09b #190 type=standard A=10234:com.xt.client U=0 visible=true visibleRequested=true mode=fullscreen translucent=false sz=4}bounds=[0,0][1080,2340]* ActivityRecord{75f3f53 u0 com.xt.client/.activitys.test.Test2Activity} t190}* ActivityRecord{777cf91 u0 com.xt.client/.activitys.test.Test2Activity} t190}* ActivityRecord{83d9d17 u0 com.xt.client/.activitys.test.Test1Activity} t190}* ActivityRecord{6979f3f u0 com.xt.client/.MainActivity} t190}* Task{e1b8d7 #191 type=standard A=10234:com.xt.client U=0 visible=false visibleRequested=false mode=fullscreen translucent=true sz=1}bounds=[0,0][1080,2340]* ActivityRecord{f91f056 u0 com.xt.client/.activitys.test.Test3Activity} t191}

我们可以看到有两个Task栈,Task1中有3个Activity记录,分别是Test1,Test2,Test2。而Task2中则只有一个Test3的记录。

此时,我们做一个改动,把Test2设置为singleTop类型,如下:

        <activity android:name="com.xt.client.activitys.test.Test1Activity" /><activity android:name="com.xt.client.activitys.test.Test2Activity"android:launchMode="singleTop" /><activityandroid:name="com.xt.client.activitys.test.Test3Activity"android:launchMode="singleInstance" />

同样的跳转顺序:Test1->Test2->Test3->Test2

结果如下:

      Application tokens in top down Z order:* Task{54bb09b #190 type=standard A=10234:com.xt.client U=0 visible=true visibleRequested=true mode=fullscreen translucent=false sz=4}bounds=[0,0][1080,2340]* ActivityRecord{777cf91 u0 com.xt.client/.activitys.test.Test2Activity} t190}* ActivityRecord{83d9d17 u0 com.xt.client/.activitys.test.Test1Activity} t190}* Task{e1b8d7 #191 type=standard A=10234:com.xt.client U=0 visible=false visibleRequested=false mode=fullscreen translucent=true sz=1}bounds=[0,0][1080,2340]* ActivityRecord{f91f056 u0 com.xt.client/.activitys.test.Test3Activity} t191}

我们发现,只有Task2仍然只有一条Test3的记录,但是Task1中,只有两条记录了,分别为Test1和Test2。相对于上一次实验,这次少了一个Test2的记录。

Test3跳转Test2的流程图如下,前台任务栈从Task1切换到了Task2,并且Test2没有新建,而是直接复用栈顶的实例对象。

总结:

总结一下,singleTop类型的启动方式,当从别的Task任务栈切换回当前任务栈时,如果栈顶实例就是同样的Activity,则直接进行复用,并且通过onNewIntent方法进行通知。

四.singleTask类型

singleTask类型其实就是singleTop类型的增强版,我们来看下他们的区别。

官方解释

        <!-- If, when starting the activity, there is already a task runningthat starts with this activity, then instead of starting a newinstance the current task is brought to the front.  The existinginstance will receive a call to {@link android.app.Activity#onNewIntentActivity.onNewIntent()}with the new Intent that is being started, and with the{@link android.content.Intent#FLAG_ACTIVITY_BROUGHT_TO_FRONTIntent.FLAG_ACTIVITY_BROUGHT_TO_FRONT} flag set.  This is a supersetof the singleTop mode, where if there is already an instanceof the activity being started at the top of the stack, it willreceive the Intent as described there (without theFLAG_ACTIVITY_BROUGHT_TO_FRONT flag set).  See the<a href="{@docRoot}guide/topics/fundamentals/tasks-and-back-stack.html">Tasks and BackStack</a> document for more details about tasks.-->

翻译后:

在启动Activity的时候,如果栈中存在一个这样的Activity,会通过在当前栈中把Activity对象带到前台的方式来替代新创建一个对象。启动的时候那个已存在的实例对象中onNewIntent方法会收到通知,并且会有Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT的标记。这是singleTop类型的扩展,如果目标Activity就处于栈顶部,则不会有FLAG_ACTIVITY_BROUGHT_TO_FRONT标记。

实验验证

我们采取和singeTop类似的方式,仍然进行对比实验。

仍然是三个Activity,其中Test1Activity设置为singleTask的模式,如下:

        <activity android:name="com.xt.client.activitys.test.Test1Activity" /><activity android:name="com.xt.client.activitys.test.Test2Activity" /><activity android:name="com.xt.client.activitys.test.Test3Activity"android:launchMode="singleInstance" />

区别于singeTop中的方式,我们这里设置Test3跳转回Test1。

设置如下跳转顺序:Test1->Test2->Test3->Test1

进行操作,使用adb命令捕获栈结构如下:

      Application tokens in top down Z order:* Task{d44dd11 #198 type=standard A=10234:com.xt.client U=0 visible=true visibleRequested=true mode=fullscreen translucent=false sz=4}bounds=[0,0][1080,2340]* ActivityRecord{5902bb5 u0 com.xt.client/.activitys.test.Test1Activity} t198}* ActivityRecord{46c4832 u0 com.xt.client/.activitys.test.Test2Activity} t198}* ActivityRecord{6e48322 u0 com.xt.client/.activitys.test.Test1Activity} t198}* Task{9bdbdf4 #199 type=standard A=10234:com.xt.client U=0 visible=false visibleRequested=false mode=fullscreen translucent=true sz=1}bounds=[0,0][1080,2340]* ActivityRecord{f0693c7 u0 com.xt.client/.activitys.test.Test3Activity} t199}

Task1中有Test1,Test2,Test1三条记录,Task2中只有Test3一条记录。

我们再把Test1改为singleTask类型,如下:

        <activity android:name="com.xt.client.activitys.test.Test1Activity" android:launchMode="singleTask" /><activity android:name="com.xt.client.activitys.test.Test2Activity" /><activity android:name="com.xt.client.activitys.test.Test3Activity"android:launchMode="singleInstance" />

同样的跳转顺序:Test1->Test2->Test3->Test1,再次进行实验,结果如下:

      Application tokens in top down Z order:* Task{9de4b6a #200 type=standard A=10234:com.xt.client U=0 visible=true visibleRequested=true mode=fullscreen translucent=false sz=2}bounds=[0,0][1080,2340]* ActivityRecord{4bdcfd7 u0 com.xt.client/.activitys.test.Test1Activity} t200}* Task{af6f1f0 #201 type=standard A=10234:com.xt.client U=0 visible=false visibleRequested=false mode=fullscreen translucent=true sz=1}bounds=[0,0][1080,2340]* ActivityRecord{66c6a33 u0 com.xt.client/.activitys.test.Test3Activity} t201}

这时候我们发现区别于上一个实验,这时Task1中只有一条Test1的记录了。

整个流程如下图所示,Test3中启动Test1的时候,前台任务栈从Task2切换到Task1,并且直接把Task1中Test2记录进行出栈操作,此时显示在前台的就是Test1了。

总结:

使用singleTask类型后,如果发现目标任务栈Task中存在相同的Activity实例时,则会出栈该实例上面的所有其它类型的实例,从而让该实例展示到前台。

六.singleInstancePerTask

singleInstancePerTask由其名可知,是singleInstance类型的增强版,其实在我看来,更像是singleInstance和singleTask的结合体,接下来我们来看下区别。

官方解释

<!-- The activity can only be running as the root activity of the task, the first activitythat created the task, and therefore there will only be one instance of this activityin a task. In constrast to the {@code singleTask} launch mode, this activity can bestarted in multiple instances in different tasks if the{@code FLAG_ACTIVITY_MULTIPLE_TASK} or {@code FLAG_ACTIVITY_NEW_DOCUMENT} is set.-->

翻译后:

Activity只能作为Task栈的根结点(第一个被创建)运行,因此栈中只可能有一个该Activity的实例。对比singleTask类型,如果设置了FLAG_ACTIVITY_MULTIPLE_TASK标记该Activity可以在不同的栈生成多个不同的实例。

实验验证

设置三个Activity,其中Test3Activity设置为singleInstancePerTask的模式,如下:

<activity android:name="com.xt.client.activitys.test.Test1Activity" />
<activity android:name="com.xt.client.activitys.test.Test2Activity" />
<activityandroid:name="com.xt.client.activitys.test.Test3Activity"android:launchMode="singleInstancePerTask" />

设置如下跳转顺序:Test1->Test2->Test3->Test1->Test2->Test3->Test1

进行操作,使用adb命令捕获栈结构如下:

      Application tokens in top down Z order:* Task{e77ae1e #206 type=standard A=10234:com.xt.client U=0 visible=true visibleRequested=true mode=fullscreen translucent=false sz=2}bounds=[0,0][1080,2340]* ActivityRecord{a818f11 u0 com.xt.client/.activitys.test.Test1Activity} t206}* ActivityRecord{632e259 u0 com.xt.client/.activitys.test.Test3Activity} t206}* Task{6ef6ec0 #205 type=standard A=10234:com.xt.client U=0 visible=false visibleRequested=false mode=fullscreen translucent=true sz=3}bounds=[0,0][1080,2340]* ActivityRecord{9918e35 u0 com.xt.client/.activitys.test.Test2Activity} t205}* ActivityRecord{25df40c u0 com.xt.client/.activitys.test.Test1Activity} t205}

可以看到,虽然启动了两次Test3,但是仍然只有两个Task栈,可以证明singleInstancePerTask类型是栈单例的,一个被声明的Activity只会拥有唯一的一个栈(不设置标记的前提下)。

如下图所示,区别于singleInstance类型的是,在这个归属Test3的栈中,是可以放入其它的Activity的,比如这里的Test1。

总结

singleInstancePerTask类型的启动方式中,

如果不存在包含目标Activity的栈,则创建一个新的Task,这个Task中是目标Activity所独有的,并且只会创建一次,后续如果在启动其它的Activity,这些新的Acitivty仍然当前的task栈。

如果存在包含目标Activity的栈,则把包含目标Activity的Task栈挪到前台,并且把该栈中目标Activity上面的所有Activity进行出栈操作,从而实现目标Activity显示在前台的效果。

当然,如官方文档所描述,如果启动singleInstancePerTask类型的Activity时,同时设置FLAG_ACTIVITY_MULTIPLE_TASK标记,应该是可以启动多个包含目标Activity的Task栈的,这里就不做实验了。

扩展性问题:

问题1:如果一个Task中的Activity全部出栈,会退到哪里?

答:假设Task1启动了Task2,那么Task2中的Activity如果全部出栈,就会把Task1推到前台,Task1中栈顶的Activity就会被显示。

我们以singleInstance类型中的流程为例,假设启动流程如下:

MainActivity(Task1)->Test1(Task2)->Test2(Task2)->Test3(Task3)->Test1(Task2)->Test2(Task3)->Test3(Task2)。

最终Test3属于Task2的栈,所以Task2中的4个Activity记录全部出栈后,会返回Task1的MainActivity,而不是Test2。

问题2:如何区分是首次创建还是从栈中返回的?

答:这个注释中就告诉我们了,栈中复用的回调用onNewIntent方法。

问题3:如何区分是从栈顶复用还是栈中复用的?

答:首先解释下栈顶复用还是栈中复用。如下图所示,如果启动的是Test3,就是栈顶复用,如果启动的是Test2或者Test1,那么就是栈中复用。

这个其实官方文档的注释中也告诉我们结果了,如果是栈中复用,则onNewIntent方法中,其flags参数中会包含Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT标记,可以通过这个来区别。

Activity的5种启动模式详解(新增singleInstancePerTask类型)相关推荐

  1. Android Activity的4种启动模式详解(示例)

    转载请注明出处:http://www.cnblogs.com/Joanna-Yan/p/5233269.html 先介绍下Android对Activity的管理,Android采用Task来管理多个A ...

  2. Activity生命周期及启动模式详解

    1.Activity生命周期 1.正常情况: (1) onCreate: 表示 Activty 正在被创建,这是 Activity 生命周期的第一个方法,可以做一些初始化的工作,比如:加载布局,绑定控 ...

  3. 活动的四种启动模式详解

    android:launchMode 目录 android:launchMode 前言 概念说明 standard singleTop singleTask singleInstance Codes演 ...

  4. UEFI与 Legacy BIOS两种启动模式详解

    参考链接1 参考链接2 (1). UEFI启动模式 与 legacy启动模式 legacy启动模式: 就是这么多年来PC一直在使用的启动方式(从MBR中加载启动程序),UEFI BIOS作为一种新的B ...

  5. 【OS基础】UEFI与 Legacy BIOS两种启动模式详解

    uefi和legacy是两种不同的引导方式,uefi是新式的BIOS,legacy是传统BIOS.你在UEFI模式下安装的系统,只能用UEFI模式引导:同理,如果你是在Legacy模式下安装的系统,也 ...

  6. Activity的启动模式详解

    Activity的启动模式详解 Activity有四种载入模式:standard(默认), singleTop, singleTask和 singleInstance. (1).standard(默认 ...

  7. Android系统(187)---最易懂的Activity启动模式详解

    Android基础:最易懂的Activity启动模式详解 前言 Android基础中,Activity的启动模式非常重要 本文将全面介绍 Activity的启动模式 目录 目录 1. 定义 即Acti ...

  8. Android Activity Launch Mode 启动模式详解

    简介 android:launchMode 属性能设置 Activity 对象启动时是否使用已有的实例还是多次创建,会使得交互设计更加良好,也能避免很多问题. 它是 Androidmanifest.x ...

  9. Android中Activity启动模式详解

    在Android中每个界面都是一个Activity,切换界面操作其实是多个不同Activity之间的实例化操作.在Android中Activity的启动模式决定了Activity的启动运行方式. An ...

最新文章

  1. 成功从小公司跳槽!35岁的程序员被裁
  2. 小程序实现图片的放大预览
  3. 基于 Azure 的认知服务将文本合成语音
  4. 基于web的通用文本标注工具MarkTool in NLP
  5. ​​​​​​​sokit v1.3抓手机应用socket数据包: Socket是传输控制层协议,WebSocket是应用层协议。
  6. 分享一个模拟真实热带雨林环境的有声动态屏保。呵护一下眼睛
  7. MIMO系统的信号检测
  8. 计算机中vlookup函数公式,Excel表中VLOOKUP函数使用方法和操作实例
  9. 异数OS 星星之火(一)-- 异数OS-织梦师云 用户使用手册
  10. enovia使用富文本小结
  11. jsd2205-csmall-passport(Day13)
  12. xlinx芯片JTAG烧录
  13. Qt项目中,绘制只有两个圆角的矩形及QPainterPath类的应用
  14. 听话的苹果-第11届蓝桥杯Scratch选拔赛真题精选
  15. kafka代码初步涉猎,用代码发送消息到客户端
  16. 部分TD-SCDMA缩写含义
  17. 基于Bmob平台的推送功能
  18. 智能取餐柜“重出江湖”引发的思考
  19. ue4初级UI设置一(游戏的开始界面)
  20. PCI总线的工作原理?

热门文章

  1. 搬家货运系统软件开发功能
  2. 安卓系统刷机怎么刷机_安卓手机刷机教程
  3. MATLAB软件GUI应用程序
  4. ShaderForge-模型拉扯效果
  5. GBase 8c 词典-同义词词典
  6. Android App设计小结
  7. 提高写作水平的十条建议
  8. Linux下将swf文件用浏览器读取打开(html、html5嵌入swf格式文件)
  9. 基于GIS的省级高速公路路面管理系统框架研究
  10. 积分兑换如何实现的呢