我们都曾羡慕别人,却忘了,我们也曾是别人羡慕的我们。

前言

最近的任务呐,真是让人蛋碎一地,各种被锤。

不过比较 nice 的是,推送凑齐了,可以整理一篇咯~

点滴积累吧。

跟着老大~

前期调研

移动端发展到现在,各种推送 SDK 真的琳琅满目,让人看花了眼。

这里就挑我用过的几个来做一个简单对比,毕竟鸡老大说了,连基本的论证对比都没,你还玩个锤子(我瞎编的)。

下面从我个人关注的几个维度进行简单的对比 (❌:代表不支持,✅:代表支持。特殊情况单独注明)

类别 极光 友盟 Mob
离线(厂商通道) 免费服务不支持,高级版以及私有云支持(华为、小米、vivo、OPPO、魅族、FCM) 支持小米、华为、魅族、OPPO、vivo系统级下发通道 支持华为、小米、魅族、OPPO、vivo厂商级通道以及 FCM
是否支持设置别名
Flutter 支持

对于小司而言,价格是一个重点,真的贼羡慕动不动就开通 VIP 或者 Pro 的小伙伴,酸了。

针对以上三种,个人觉得:

  • 如果当前应用仅仅在线推送,极光、Mob、友盟都可以;
  • 如果当前应用仅仅支持国内而且还要支持离线推送,那么友盟以及 Mob 不二人选;
  • 如果土豪级别应用,又支持国外,那么直接极光 VIP/Pro 走起,一键式支持国内厂商以及 FCM 海外推送;
  • 反之,想支持海外,老老实实接入 FCM 吧。

有点茫然,明明看着 Mob 支持 FCM,但是官网上却没看到写。

对了,今天偶然看到小伙伴对极光推送的一些讨论:

好坏不多说,纯技术分享,不涉及其他东西,自行选择吧。

没辙,一分钱,难倒英雄汉!还好,哈哈哈。

由于项目私密性,这里就不放置对应的效果图了。PS:其实我还是蛮喜欢放个效果图的,至少一上来就能看到效果,But 涉密,阿哦~

一、友盟厂商申请对应 key

由于我司账号问题,无法集入所有厂商,尴尬啊。

毕竟鸡老大也说过,不对未接触的事物发表任何意见。

所以这里按照友盟所需要对应厂商资料进行依次注册填入即可:

推荐几个不错的厂商推送指南:

  • 友盟 - 厂商通道集成文档
  • Mob - 第三方厂商推送指南

图忒多了,而且没啥难点,按照集成对应平台提供资料进行对应厂商注册吧。

二、Android 原生集成 - 友盟 v6.0.5

当初采用友盟原因如下:

  • 支持厂商推送
  • 方便运营小伙伴直接友盟查看所有数据

1.1 添加友盟依赖

前期在友盟平台创建当前应用之类的就不谈了,注意推送 Android 版需要绑定包名。

关于友盟推送需要离线厂商推送,所以涉及到大部分的配置项,这里我直接提取一个 gradle,避免主 gradle 各种杂乱不堪。

首先我们在项目根目录下添加友盟的远程库:

// Top-level build file where you can add configuration options common to all sub-projects/modules.buildscript {repositories {google()jcenter()// 这里maven { url 'https://dl.bintray.com/umsdk/release' }}dependencies {// 。。。 }
}allprojects {repositories {flatDir {dirs 'libs'}google()jcenter()maven { url 'https://jitpack.io' }// 这里maven { url 'https://dl.bintray.com/umsdk/release' }}
}task clean(type: Delete) {delete rootProject.buildDir
}

随后在 app 下创建友盟依赖的 gradle,这里注意由于我司开发者账号原因,并没能集成所有厂商:

dependencies {// 友盟推送// 基础组件库依赖(必须) Push 605 版本必须升级新版本 Common SDKimplementation 'com.umeng.umsdk:common:2.2.2'implementation 'com.umeng.umsdk:utdid:1.5.2'// 友盟 push 相关依赖(必须)implementation 'com.umeng.umsdk:push:6.0.5'implementation 'com.umeng.umsdk:alicloud-httpdns:1.2.5'implementation 'com.umeng.umsdk:alicloud-utils:1.1.5'implementation 'com.umeng.umsdk:alicloud_beacon:1.0.1'implementation 'com.umeng.umsdk:agoo-accs:3.3.8.8-open-fix2'implementation 'com.umeng.umsdk:agoo_networksdk:3.5.5'implementation 'com.umeng.umsdk:agoo_tlog:3.0.0.17'implementation 'com.umeng.umsdk:agoo_tnet4android:3.1.14.9'// ====== 厂商集成 Start// 小米 Push 通道implementation 'com.umeng.umsdk:xiaomi-push:3.7.0'implementation 'com.umeng.umsdk:xiaomi-umengaccs:1.1.4'// 华为 Push 通道implementation 'com.umeng.umsdk:huawei-basetb:2.6.3.306'implementation 'com.umeng.umsdk:huawei-pushtb:2.6.3.306'implementation 'com.umeng.umsdk:huawei-umengaccs:1.2.4'// Oppo Push 通道implementation 'com.umeng.umsdk:oppo-push:2.0.2'implementation 'com.umeng.umsdk:oppo-umengaccs:1.0.6'// vivo Push 通道implementation 'com.umeng.umsdk:vivo-push:2.3.5'implementation 'com.umeng.umsdk:vivo-umengaccs:1.1.0'
}

最后在主 gradle 也就是 app 下的 gradle 添加对此依赖:

// 友盟推送
apply from: 'UMeng_Push.gradle'

1.2 初始化友盟推送并设置通知栏点击动作

在 Application 中进行友盟推送的初始化以及点击通知栏后操作:

    private fun initUMengSettings() {// 初始化 SDKmContext?.let {UMConfigure.init(mContext,K_RELEASE_UMENG,it.getString(R.string.code_umeng),UMConfigure.DEVICE_TYPE_PHONE,K_UMENG_SECRET)initUMengPush(it)}}/*** 初始化友盟消息推送*/private fun initUMengPush(context: Context) {// 获取消息推送代理示例val pushAgent = PushAgent.getInstance(context)// 注册推送服务,每次调用 register 方法都会回调该接口pushAgent.register(mIUmengRegisterCallback)// 设置点击通知栏打开操作pushAgent.notificationClickHandler = mNotificationClickHandlerinitUMengPushSettings(pushAgent)}/*** 注册推送服务*/private val mIUmengRegisterCallback = object : IUmengRegisterCallback {override fun onSuccess(deviceToken: String?) {pwcLog("-------> 注册成功:deviceToken:--------> $deviceToken")}override fun onFailure(s: String?, s1: String?) {pwcLog("-------> 注册失败:s ---> $s ||| s1 ---> $s1")}}/*** 点击通知栏 后续操作*/private val mNotificationClickHandler = object : UmengNotificationClickHandler() {/*** 处理用户点击通知栏消息*/override fun dealWithCustomAction(context: Context?, uMessage: UMessage?) {super.dealWithCustomAction(context, uMessage)context ?: returnuMessage ?: return// 后台接口传递过来的参数都在 map 中val extraMap = uMessage.extra// 这里演示下获取俩个值val openType = extraMap["type"]val openID = extraMap["id"]// 。。。}}/*** 推送基础信息配置*/private fun initUMengPushSettings(pushAgent: PushAgent) {// 设置最多显示通知条数 参数 number 可以设置为 0~10 之间任意整数。当参数为 0 时,表示不合并通知;pushAgent.displayNotificationNumber = 0// 设置客户端允许声音提醒pushAgent.notificationPlaySound = MsgConstant.NOTIFICATION_PLAY_SDK_ENABLE// 设置客户端允许呼吸灯点亮pushAgent.notificationPlayLights = MsgConstant.NOTIFICATION_PLAY_SDK_ENABLE// 设置客户端允许震动pushAgent.notificationPlayVibrate = MsgConstant.NOTIFICATION_PLAY_SDK_ENABLE// 通知免打扰 SDK默认在“23:00”到“7:00”之间收到通知消息时不响铃,不振动,不闪灯pushAgent.setNoDisturbMode(23, 0, 7, 0)// 设置冷却时间 避免一分钟内出现多条通知而被替换pushAgent.muteDurationSeconds = 600}

1.3 离线推送支持

在 Application 中对应初始化厂商通道即可:

/*** @author:heliquan* @date:2020-05-07* @desc:厂商推送*/
class PushSDKBizImpl : AppInterface {private var mContext: Context? = nulloverride fun onCreate(knowledgeCore: KnowledgeCore) {if (mContext == null) {mContext = knowledgeCore.applicationContext}registerPush(knowledgeCore)}private fun registerPush(knowledgeCore: KnowledgeCore) {// 小米 Push registerMiPushRegistar.register(mContext, K_XIAOMI_ID, K_XIAOMI_KEY)// 华为 Push registerHuaWeiRegister.register(knowledgeCore)// OPPO Push registerOppoRegister.register(mContext, K_OPPO_KEY, K_OPPO_SECRET)// Vivo Push registerVivoRegister.register(mContext)}// 。。。
}

很多时候我们都希望,即使用户当前未使用 App,或者说当前的 App 处于被杀死的状态,后台推送消息依然想被前台接收。

那么如果想实现离线推送,我们还要完善下面的一步:


import com.umeng.message.UmengNotifyClickActivity
import org.android.agoo.common.AgooConstants/*** @author HLQ_Struggle* @date 2020/5/7* @desc* 小米、华为等对后台进程做了诸多限制。若使用一键清理,应用的channel进程被清除,将接收不到推送。通过接入托管弹窗功能,可有效防止以上情况,增加推送消息的送达率。 */
class PushActivity : UmengNotifyClickActivity() {private val mSelfActivity = PushActivity@ thisoverride fun onMessage(intent: Intent?) {super.onMessage(intent)// 拿到数据 AgooConstants.MESSAGE_BODY 进行对应后续操作val offlinePushBean =intent?.getStringExtra(AgooConstants.MESSAGE_BODY)?.let {GsonUtil.fromJson(it,  // 这里需要将获取到的json再次进行格式化object : TypeToken<OfflinePushBean>() {})}// 例如我这里直接跳转启动页,然后慢慢跳转目标页offlinePushBean?.extra?.let {val intent = Intent(mSelfActivity, SplashActivity::class.java)intent.putExtra(K_OFFLINE_PUSH_ID, it.id)intent.putExtra(K_OFFLINE_PUSH_TYPE, it.type)intent.flags = Intent.FLAG_ACTIVITY_NEW_TASKstartActivity(intent)finish()}}}

当然 AndroidManifest 此 Activity 内容附上:

<activityandroid:name=".ui.activity.push.PushActivity"android:exported="true"android:launchMode="singleTask"android:theme="@style/FullScreenTransparentTheme" />

到此,友盟 Android 集成推送已完成~

三、Android 原生集成 - FCM

Google 爸爸 GCM 集成的真的是贼贴心,业界楷模啊。

我不吹,你自己瞧~

附上 FCM 地址:

  • firebase.google.com/?hl=zh-cn

需要注意的几点:

  • 记得测试的时候,ke xue 上网,我之前就遇到这么一个情况,显示发送了,结果 App 收不到,最后才反应过来,没有 ke xue 上网。
  • 国内的手机一般没有 Google 全家桶,或者说 Google 服务,需要去豌豆荚中下载。

3.1 FCM 前期配置

首先不可避免的,创建项目:

这里需要注意创建项目的一个规则:

  • 项目名称必须至少包含 4 个字符只能包含字母、数字、空格和以下字符:-!'"

按照要求输入项目名称,勾选接收条款:

添加 Google Analytics 分析:

第三步勾选对应的条款,完成项目创建:

创建期间还有个小进度,贼好看:

创建的速度很快:

3.2 FCM 集成

进入首页后,点击 Android 图标,开始 Android 接入/集成相关工作:

一共有如下四步:

  • 第一步填写对应包名以及 SHA-1,反之我是都填了。

  • 第二步下载配置文件并拷贝到 app 目录下:

  • 第三步添加对应的 SDK

  • 第四步运行验证,可忽略

当然 Google 也为我们提供了一键式的配置,但是尴尬的是,我尝试失败了,不过也算是一种方式,具体文章内容如下:

  • 将 Firebase 添加到您的 Android 项目

这里为了偷个懒,直接一张图展示了:

3.3 FCM 消息处理

在 app build 中完善下依赖:

    // FCMimplementation 'com.google.firebase:firebase-analytics:17.4.4'// FCM Message 处理implementation 'com.google.firebase:firebase-messaging:20.2.2'// FCM Message 后台处理implementation 'com.google.firebase:firebase-messaging-directboot:20.2.2'

随后创建一个 Service 用于处理 FCM 消息,这里我直接采用了接收到 Google FCM 消息后手动创建一个通知:

/*** @author HLQ_Struggle* @date 2020/7/8* @desc*/
class MyFirebaseMessagingService : FirebaseMessagingService() {/*** 处理 FCM 消息*/override fun onMessageReceived(remoteMessage: RemoteMessage) {Log.d(TAG, "From: ${remoteMessage.from}")// Check if message contains a data payload.if (remoteMessage.data.isNotEmpty()) {Log.e(TAG, "Message data payload: ${remoteMessage.data}")// 这里包含后台传递自定义的值val remoteMessageMap = remoteMessage.datasendNotification(remoteMessageMap["type"].toString(),remoteMessageMap["title"].toString(),remoteMessageMap["content"].toString())}remoteMessage.notification?.let {Log.e(TAG, "Message Notification Body: ${it.body}")}}/*** 令牌更新回调 FCM 没有设置别名这么一说 所以需要我们通过令牌的方式去指定推送*/override fun onNewToken(token: String) {Log.d(TAG, "Refreshed token: $token")sendRegistrationToServer(token)}/*** 保存令牌*/private fun sendRegistrationToServer(token: String?) {Log.d(TAG, "sendRegistrationTokenToServer($token)")}/*** Create and show a simple notification containing the received FCM message.** @param messageBody FCM message body received.*/private fun sendNotification(type: String, title: String, content: String) {val intent = Intent(this, SplashActivity::class.java)intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)val pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,PendingIntent.FLAG_ONE_SHOT)val channelId = getString(R.string.default_notification_channel_id)val defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)val notificationBuilder = NotificationCompat.Builder(this, channelId).setSmallIcon(R.mipmap.ic_launcher_round).setContentTitle(title).setContentText(content).setAutoCancel(true).setSound(defaultSoundUri).setContentIntent(pendingIntent)val notificationManager =getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager// Since android Oreo notification channel is needed.if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {val channel = NotificationChannel(channelId,"Channel human readable title",NotificationManager.IMPORTANCE_DEFAULT)notificationManager.createNotificationChannel(channel)}notificationManager.notify(0 /* ID of notification */, notificationBuilder.build())}companion object {private const val TAG = "MyFirebaseMsgService"}
}

在 AndroidManifest 中 Service:

<serviceandroid:name=".service.MyFirebaseMessagingService"android:directBootAware="true"android:exported="false"><intent-filter><action android:name="com.google.firebase.MESSAGING_EVENT" /></intent-filter>
</service>

3.4 FCM 其它配置

当然还有一些可修改的内容,例如:

  • icon
  • notification_color

我是直接采用默认的了。这里官网找到的,贴出来,避免小伙伴有需求还的找。

    <meta-dataandroid:name="com.google.firebase.messaging.default_notification_icon"android:resource="@drawable/appicon" /><meta-dataandroid:name="com.google.firebase.messaging.default_notification_color"android:resource="@color/styleTitleOrange" /><meta-dataandroid:name="firebase_messaging_auto_init_enabled"android:value="false" /><meta-dataandroid:name="firebase_analytics_collection_enabled"android:value="false" />

到此,FCM 完毕~

四、Flutter Android 集成 - Mob

此模块在厂商相关信息完善时,集成仅仅几分钟~

相对于 Flutter 接入推送,不得不说 Mob 做的贼优秀,直接 Flutter 插件搞起,大大的方便了 Flutter 开发者,先比个小心心~ ❤️

附上 Mob 插件地址:

  • pub.dev/packages/mo…

以及对应 Flutter 的集成指南:

  • mob.com/wiki/detail…

Mob 的文档,真的是良心,集成贼简单,入手超级方便,一起来看。

4.1 添加 Mob 插件依赖

  • mobpush_plugin: ^1.1.5

4.2 配置 Android 基本环境

首先,根目录下的 build 文件添加如下:

dependencies {// 。。。classpath 'com.mob.sdk:MobSDK:+'
}

其次,app 下 build 文件添加对应的配置项,这里关于 Mob 的配置可单独提取一个 gradle 文件,这里当初为了实现而实现,就不抽离了。

导入插件:

apply plugin: 'com.android.application' // 一般项目自带有这个,所以这块的这个可以忽略
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
apply plugin: 'com.mob.sdk'

Mob 推送的相关配置:

  • 基础的 appKey 以及 appSecret
  • 厂商对应的 key 以及其它信息

代码如下:

MobSDK {appKey "Mob 提供的 App Key"appSecret "Mob 提供的 App Secret"// 配置MobPushMobPush {// 配置厂商推送(可选配置,不需要厂商推送可不配置,需要哪些厂商推送只需配置哪些厂商配置即可)devInfo {// 配置小米厂商推送XIAOMI {appId "您的小米平台appId"appKey "您的小米平台appKey"}// 配置华为厂商推送HUAWEI {appId "您的华为平台appId"}// 配置魅族厂商推送MEIZU {appId "您的魅族平台appId"appKey "您的魅族平台appKey"}// 配置FCM厂商推送FCM {// 设置默认推送通知显示图标iconRes "@mipmap/default_ic_launcher"}// 配置 OPPO 厂商推送OPPO {appKey "您的OPPO平台appKey"appSecret "您的OPPO平台appSecret"}// 配置VIVO厂商推送VIVO {appId "您的VIVO平台appId"appKey "您的VIVO平台appKey"}}}
}

接着去 MainActivity 中注册下,一般也无需操作,我这里是之前写过一个通道,附上部分代码:

import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugins.GeneratedPluginRegistrantclass MainActivity : FlutterActivity() {override fun configureFlutterEngine(flutterEngine: FlutterEngine) {GeneratedPluginRegistrant.registerWith(flutterEngine) }}

最后就是对于初始化 Mob 以及接受到 Mob 消息推送如何处理了,蛮简单的,这里说下几个点吧:

  • 由于项目需求设置以用户名为别名,所以也涉及到了添加别名这个操作,而在这里则是本地维护了一个状态,避免多次设置重复别名;
  • 其次需求是接收到消息推送执行刷新操作,所以我在这里直接接收到推送消息后通过 eventBus 发送状态去执行数据更新操作了。

以下是部分代码,仅供参考:

  /// 目前仅支持 Android 端推送void initMobPush() {getCacheValue(memberInfo).then((userCache) {MemberInfoBean memberInfoBean = memberInfoBeanFromJson(userCache);if (Platform.isAndroid) {// 设置隐私协议授权状态MobpushPlugin.updatePrivacyPermissionStatus(true);getCacheValue(pushAliaState).then((result) {LogUtil.e(" ===> 获取 Mob 注册状态");if (result == null) {LogUtil.e(" ===> Mob 未注册 需要注册");MobpushPlugin.setAlias(memberInfoBean.memberInfo.id).then((Map<String, dynamic> map) {LogUtil.e(" ===> 设置 Mob 推送别名: -> res: ${map['res']} ");if (map['errorCode'] == '0') {// 注册成功 本地缓存状态setCacheValue(bool, pushAliaState, true);}});}});// 添加推送回调MobpushPlugin.addPushReceiver(_onEvent, _onError);}});}void _onEvent(Object event) {LogUtil.e('  接收到消息内容:$event');eventBus.fire(PushEvent(true));}void _onError(Object event) {}

End

本文内容较多,主要是整理前段时间遇到的问题,其实也不算啥问题吧,主要各种账号前期准备不足,后期产品调整频繁导致。

基本都附上了源码。

菜鸡一枚,欢迎各位大佬指正~

最后

在这里我也分享自己收录整理一份Android核心笔记,里面对Android相关技术有详细的讲解,希望可以帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习,可以分享给身边好友一起学习


有需要的朋友可以私信我【666】获取。

粉丝交流扣裙:

Android Notes | 集成推送那点事(友盟/Mob(Flutter)/FCM)相关推荐

  1. flutter友盟分享_集成推送那点事-友盟/Mob-Flutter/FCM

    第 97 次推文 LZ-Says 我们都曾羡慕别人,却忘了,我们也曾是别人羡慕的我们. 推荐直接拉到底阅读原文- 前言 最近的任务呐,真是让人蛋碎一地,各种被锤. 不过比较 nice 的是,推送凑齐了 ...

  2. 友盟消息推送服务器demo,umeng友盟消息推送功能集成

    umeng友盟消息推送功能集成(本人使用的是eclipse开发) 1.首先请自行观看友盟消息推送集成的API文档. 观看地址如下: 2.集成步骤如下 下载sdk 注意:有两种sdk如果用户已经集成支付 ...

  3. 友盟推送服务器配置文档,友盟使用指南

    概念说明 AppKey, Umeng Message Secret , App Master Secret 注册友盟账号,系统会自动生成 AppKey, Umeng Message Secret , ...

  4. 第三方推送(小米华为友盟)接入实践

    0,前言 这几天接了一下友盟,小米,华为三方的推送. 总的流程下来,小米的api是最友好的,华为的文档和demo有点脱节.这两个推送在特定的手机上都挺稳定的的. 友盟的就有点麻烦,过程中遇到几个问题 ...

  5. 友盟推送 java_java 后台调用友盟推送 如何设置ios 的 title?

    查看官方友盟推送文档 文档的意思我一开始也没看懂,后来发现这里可能是这个意思:你可以传进来字符串或者json串,如果是字符串,UMeng那边就默认它是内容,如果是json串的话,格式要像它给的那样,U ...

  6. 集成推送(极光+小米+华为)总结(java服务端)

    公司app集成了极光推送,前前后后在这上面费了不少时间了,总结下自己的理解和遇到的问题.  只用过极光推送,所以下面都以极光推送为例.(后面新增小米和华为) 1..都有什么品牌的推送服务? 集成什么品 ...

  7. android与苹果 推送,科普下安卓和苹果的推送区别

    看到很多人说苹果推送比安卓好太多,安卓关掉app就没法收到推送消息,作为从业者,来给大家科普下安卓和苹果的推送区别. 首先上苹果推送的整体流程图 简单描述一下,开发者先接入苹果推送服务,有消息需要推送 ...

  8. 友盟小米收不到推送消息_一个轻量级、可插拔的Android消息推送框架。一键集成推送(极光推送、友盟推送、华为、小米推送等)...

    XPush 一个轻量级.可插拔的Android消息推送框架.一键集成推送(极光推送.友盟推送.华为.小米推送等),提供有效的保活机制,支持推送的拓展,充分解耦推送和业务逻辑,解放你的双手! 在提iss ...

  9. Android开发之推送服务(三) 集成Oppo和vivo推送

    Oppo推送服务,也是在Oppo手机中使用的比较多.而且现在Oppo和Vivo两款手机最早提出美颜功能,所以这两款手机在市场上的占有率还是比较高的. Oppo推送目前已经开发注册,Vivo目前只对部分 ...

  10. Android 多厂商推送集成

    前言 按劳分配,多劳多做.好不容易集成完了个推的推送 SDK,美滋滋的准备划一会儿水,鸟哥吩咐为了保证应用杀死后也可以接收到推送,并且降低服务端的维护多渠道的开发成本,还得集成下个推的多厂商渠道.等等 ...

最新文章

  1. 记一次单机系统的性能优化:最后竟是 TCP 的锅
  2. 周志华教授:如何做研究与写论文?(附PPT下载)
  3. sql中where和on的区别
  4. [置顶] CopyU!v2插件合集 [2013年7月18日更新]
  5. FPGA资源平民化的新晋- F3 技术解析
  6. java如何让线程阻塞_Java中如何使一个线程进入阻塞态?
  7. python基础编程语法-Python基础语法介绍:面向对象编程(上)
  8. virtualenv 安装及使用[转]
  9. HEVC 推出专利使用费标准
  10. 看着2022年世界杯,我无比怀念98世界杯
  11. 合肥学院计算机论文,合肥学院本科生毕业论文.doc
  12. 数据库——SQL语言建立供应商表S,零件表P,工程表J,供应表SPJ
  13. 微信公众号编辑器的附件功能(如Word、Excel、Pdf等)
  14. C语言——基本编写规范
  15. 财商帮解读:高质量的社群都离不开这10个关键要素!
  16. 长沙航空职业技术学院计算机系,长沙航空职业技术学院机器人专业怎么样
  17. 网络编程之listen函数
  18. 定向推送,虚假宣传,资本助力的团油有谁撑腰?
  19. 广西免考职称英语计算机,广西职称英语免考条件及免试人群
  20. C Primer Plus (第五版)中文版——第 10 章 数组和指针

热门文章

  1. 产品推广都有哪些方法可以用?
  2. 程序员史诗级必读书单吐血整理四个维度系列80+本书(珍藏版)
  3. iphone手机设置自定义铃声(mac环境下设置)
  4. linux 节点互信,Linux 集群节点互信ssh配置
  5. 渥太华计算机读研的好学校,加拿大硕士留学:渥太华最好的大学硕士项目
  6. PVC地板IMO船舶防火测试认证注意事项
  7. 第1章 弗洛依德——精神分析
  8. 一个故事轻松记忆常见252个英语字根(31~80)
  9. 山东CIO智库——山东省两化融合深度行龙口站成功举办
  10. 什么是常见的计算机应用软件,什么是计算机的应用软件?