请选择 进入手机版 | 继续访问电脑版

默认
打赏 发表评论 0
仿微信的IM聊天时间显示格式(含iOS/Android/Web实现)[图文+源码]

本文为即时通讯网原创分享,转载请注明出处。


1、引言


即时通讯IM应用中的聊天消息时间显示是个再常见不过的需求,现在都讲究用户体验,所以时间显示再也不能像传统软件一样简单粗地暴显示成“年/月/日 时:分:秒”这样。所以,市面上几乎所有的IM都会对聊天消息的时间显示格化做人性化处理,从而提升用户体验(使用感受会明显友好)。

这两天正在继续开发RainbowChat-Web产品,所以正需要这样的代码。但经过在即时通讯网的论坛和技术交流群里询问,以及网上的所谓仿微信例子,都不符合要求。这些例子要么简陋粗暴(有逻辑bug硬伤)、要么并不完整(可能只是随手写的练手代码,并不适合放到产品中),所以本着做技术精益求精的态度,没有现成的轮子可用,那就只能造轮子了。

那么,按怎样的显示逻辑来实现呢?作为移动端IM的王者,微信无疑处处是标杆,所以本次的消息时间显示格式,直接参照微信的实现逻辑准没错(随大流虽然没个性,但不至于非主流)。

* 提示:本文中的代码实现,是从 RainbowChat 和 RainbowChat-Web 两个IM产品中扒出来简化后的结果,是基于完全相同的算法逻辑分别用OC、Java和JavaScript实现的。如您觉得有用,可以改改直接用于您的产品,如您有更好的建议请直接回复和评论代码仅供参考,不足之外,还请见谅!

2、相关文章



3、看看微信中聊天消息的时间显示规则


先来看看微信中聊天消息的时间显示成什么样:
0-2.jpg     0-1.jpg
▲ 左图为微信主页“消息”界面、右图为聊天界面(注意聊天界面中默认带了“时:分”的显示)

来自微信官方对聊天消息时间显示的规则说明:
屏幕快照-2019-02-22-12.24.jpg
▲ 该规则的定义,主要是2、3条(本图引用自微信官方FAQ文档

4、总结一下微信中聊天消息的时间显示逻辑


参见第3节中的截图和微信官方的说明,我们可以总结出微信对于聊天消息时间显示的规则。

① 微信对于聊天消息时间显示的规则总结如下(首页“消息”界面):

  • 1)当聊天消息时间为一周之内时:当天的消息显示为“小时:分钟”形式,然后是“昨天”、“前天”,然后就是“星期几”这个样子;
  • 2)当聊天消息的时间大于一周时:直接显示“年/月/日”的时间格式。

② 微信对于聊天消息时间显示的规则总结如下(聊天内容界面):

  • 1)当聊天消息时间为一周之内时:当天的消息显示为“小时:分钟”形式,然后是“昨天 时:分”、“前天 时:分”,然后就是“星期几  时:分”这个样子;
  • 2)当聊天消息的时间大于一周时:直接显示“年/月/日 时:分”的完整时间格式。

注意:聊天内容界面里的时间格式,实际上是首页“消息”界面里的时间格式加上“时:分”后的结果,所以代码实现上这两套代码是可以重用的,无需两份代码。

好了,规则已经摸清,下面将直接上代码。

5、Android平台上的代码实现(标准Java)


5.1完整源码


/**
 * 返回指定pattern样的日期时间字符串。
 * 
 * @param dt
 * @param pattern
 * @return 如果时间转换成功则返回结果,否则返回空字符串""
 * @author 即时通讯网([url=http://www.52im.net]http://www.52im.net[/url])
 */
public static String getTimeString(Date dt, String pattern)
{
        try
        {
                SimpleDateFormat sdf = new SimpleDateFormat(pattern);//"yyyy-MM-dd HH:mm:ss"
                sdf.setTimeZone(TimeZone.getDefault());
                return sdf.format(dt);
        }
        catch (Exception e)
        {
                return "";
        }
}

/**
* 仿照微信中的消息时间显示逻辑,将时间戳(单位:毫秒)转换为友好的显示格式.
* <p>
* 1)7天之内的日期显示逻辑是:今天、昨天(-1d)、前天(-2d)、星期?(只显示总计7天之内的星期数,即<=-4d);<br>
* 2)7天之外(即>7天)的逻辑:直接显示完整日期时间。
*
* @param srcDate 要处理的源日期时间对象
* @param mustIncludeTime true表示输出的格式里一定会包含“时间:分钟”,否则不包含(参考微信,不包含时分的情况,用于首页“消息”中显示时)
* @return 输出格式形如:“10:30”、“昨天 12:04”、“前天 20:51”、“星期二”、“2019/2/21 12:09”等形式
* @author 即时通讯网([url=http://www.52im.net]http://www.52im.net[/url])
* @since 4.5
*/
public static String getTimeStringAutoShort2(Date srcDate, boolean mustIncludeTime)
{
        String ret = "";
        
        try
        {
                GregorianCalendar gcCurrent = new GregorianCalendar();
                gcCurrent.setTime(new Date());
                int currentYear = gcCurrent.get(GregorianCalendar.YEAR);
                int currentMonth = gcCurrent.get(GregorianCalendar.MONTH)+1;
                int currentDay = gcCurrent.get(GregorianCalendar.DAY_OF_MONTH);
                
                GregorianCalendar gcSrc = new GregorianCalendar();
                gcSrc.setTime(srcDate);
                int srcYear = gcSrc.get(GregorianCalendar.YEAR);
                int srcMonth = gcSrc.get(GregorianCalendar.MONTH)+1;
                int srcDay = gcSrc.get(GregorianCalendar.DAY_OF_MONTH);
                
                // 要额外显示的时间分钟
                String timeExtraStr = (mustIncludeTime?" "+getTimeString(srcDate, "HH:mm"):"");
        
                // 当年
                if(currentYear == srcYear)
                {
                        long currentTimestamp = gcCurrent.getTimeInMillis();
                        long srcTimestamp = gcSrc.getTimeInMillis();

                        // 相差时间(单位:毫秒)
                        long delta = (currentTimestamp - srcTimestamp);
                        
                        // 当天(月份和日期一致才是)
                        if(currentMonth == srcMonth && currentDay == srcDay)
                        {
                                // 时间相差60秒以内
                                if(delta < 60 * 1000)
                                           ret = "刚刚";
                                // 否则当天其它时间段的,直接显示“时:分”的形式
                                else
                                            ret = getTimeString(srcDate, "HH:mm");
                        }
                        // 当年 && 当天之外的时间(即昨天及以前的时间)
                        else
                        {
                                // 昨天(以“现在”的时候为基准-1天)
                                GregorianCalendar yesterdayDate = new GregorianCalendar();
                                yesterdayDate.add(GregorianCalendar.DAY_OF_MONTH, -1);

                                // 前天(以“现在”的时候为基准-2天)
                                GregorianCalendar beforeYesterdayDate = new GregorianCalendar();
                                beforeYesterdayDate.add(GregorianCalendar.DAY_OF_MONTH, -2);
                        
                                // 用目标日期的“月”和“天”跟上方计算出来的“昨天”进行比较,是最为准确的(如果用时间戳差值
                                // 的形式,是不准确的,比如:现在时刻是2019年02月22日1:00、而srcDate是2019年02月21日23:00,
                                // 这两者间只相差2小时,直接用“delta/(3600 * 1000)” > 24小时来判断是否昨天,就完全是扯蛋的逻辑了)
                                if(srcMonth == (yesterdayDate.get(GregorianCalendar.MONTH)+1) 
                                        && srcDay == yesterdayDate.get(GregorianCalendar.DAY_OF_MONTH))
                                {
                                            ret = "昨天"+timeExtraStr;// -1d
                                }
                                // “前天”判断逻辑同上
                                else if(srcMonth == (beforeYesterdayDate.get(GregorianCalendar.MONTH)+1) 
                                        && srcDay == beforeYesterdayDate.get(GregorianCalendar.DAY_OF_MONTH))
                                {
                                            ret = "前天"+timeExtraStr;// -2d
                                }
                                else
                                {
                                            // 跟当前时间相差的小时数
                                            long deltaHour = (delta/(3600 * 1000));

                                            // 如果小于 7*24小时就显示星期几
                                            if (deltaHour < 7*24)
                                            {
                                                String[] weekday = {"星期日","星期一","星期二","星期三","星期四","星期五","星期六"};

                                                // 取出当前是星期几
                                                String weedayDesc = weekday[gcSrc.get(GregorianCalendar.DAY_OF_WEEK)-1];
                                                ret = weedayDesc+timeExtraStr;
                                            }
                                            // 否则直接显示完整日期时间
                                            else
                                                ret = getTimeString(srcDate, "yyyy/M/d")+timeExtraStr;
                                }
                        }
            }
            else
                ret = getTimeString(srcDate, "yyyy/M/d")+timeExtraStr;
        }
        catch (Exception e)
        {
                System.err.println("【DEBUG-getTimeStringAutoShort】计算出错:"+e.getMessage()+" 【NO】");
        }
        
        return ret;
}

5.2调用示例

// 用于首页“消息”界面时
getTimeStringAutoShort2(new Date(), false);
// 用于聊天内容界面时
getTimeStringAutoShort2(new Date(), true);

5.3运行效果


3.jpg
▲ 上述代码在RainbowChat Android版上的运行效果(首页)

4.jpg
▲ 上述代码在RainbowChat Android版上的运行效果(聊天界面)

6、iOS平台上的代码实现(Objective-C)


6.1完整源码


源文件TimeTool.h:
//
//  TimeTool.h
//  RainbowChat4i
//
//  Created by JackJiang on 2018/5/8.
//  Copyright © 2018年 即时通讯网([url=http://www.52im.net]http://www.52im.net[/url]). All rights reserved.
//

#import <Foundation/Foundation.h>

@interface TimeTool : NSObject

/**
 * 仿照微信中的消息时间显示逻辑,将时间戳(单位:毫秒)转换为友好的显示格式.
 *
 * 1)7天之内的日期显示逻辑是:今天、昨天(-1d)、前天(-2d)、星期?(只显示总计7天之内的星期数,即<=-4d);
 * 2)7天之外(即>7天)的逻辑:直接显示完整日期时间。
 *
 * @param dt 日期时间对象(本次被判断对象)
 * @param includeTime YES表示输出的格式里一定会包含“时间:分钟”,否则不包含(参考微信,不包含时分的情况,用于首页“消息”中显示时)
 *
 * @return 输出格式形如:“刚刚”、“10:30”、“昨天 12:04”、“前天 20:51”、“星期二”、“2019/2/21 12:09”等形式
 * @since 1.3
 */
+ (NSString *)getTimeStringAutoShort2:(NSDate *)dt mustIncludeTime:(BOOL)includeTime;

+ (NSString *)getTimeString:(NSDate *)dt format:(NSString *)fmt;

/**
 * 获得指定NSDate对象iOS时间戳(格式遵从ios的习惯,以秒为单位)。
 */
+ (NSTimeInterval) getIOSTimeStamp:(NSDate *)dat;

/**
 * 获得指定NSDate对象iOS时间戳的long形式(格式遵从ios的习惯,以秒为单位,形如:1485159493)。
 */
+ (long) getIOSTimeStamp_l:(NSDate *)dat;

/**
 * 获得iOS当前系统时间的NSDate对象。
 */
+ (NSDate*)getIOSDefaultDate;
@end

源文件TimeTool.m:
//
//  TimeTool.m
//  RainbowChat4i
//
//  Created by JackJiang on 2018/5/8.
//  Copyright © 2018年 即时通讯网([url=http://www.52im.net]http://www.52im.net[/url]). All rights reserved.
//

#import "TimeTool.h"

@implementation TimeTool

// 仿照微信的逻辑,显示一个人性化的时间字串
+ (NSString *)getTimeStringAutoShort2:(NSDate *)dt mustIncludeTime:(BOOL)includeTime{
    NSString *ret = nil;
    NSCalendar *calendar = [NSCalendar currentCalendar];
    
    // 当前时间
    NSDate  *currentDate = [NSDate date];
    NSDateComponents *curComponents = [calendar components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay|NSCalendarUnitWeekday fromDate:currentDate];
    NSInteger currentYear=[curComponents year];
    NSInteger currentMonth=[curComponents month];
    NSInteger currentDay=[curComponents day];
    
    // 目标判断时间
    NSDateComponents *srcComponents = [calendar components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay|NSCalendarUnitWeekday fromDate:dt];
    NSInteger srcYear=[srcComponents year];
    NSInteger srcMonth=[srcComponents month];
    NSInteger srcDay=[srcComponents day];
    
    // 要额外显示的时间分钟
    NSString *timeExtraStr = (includeTime?[TimeTool getTimeString:dt format:@" HH:mm"]:@"");
    
    // 当年
    if(currentYear == srcYear) {
        long currentTimestamp = [TimeTool getIOSTimeStamp_l:currentDate];
        long srcTimestamp = [TimeTool getIOSTimeStamp_l:dt];
        
        // 相差时间(单位:秒)
        long delta = currentTimestamp - srcTimestamp;
        
        // 当天(月份和日期一致才是)
        if(currentMonth == srcMonth && currentDay == srcDay) {
            // 时间相差60秒以内
            if(delta < 60)
                ret = @"刚刚";
            // 否则当天其它时间段的,直接显示“时:分”的形式
            else
                ret = [TimeTool getTimeString:dt format:@"HH:mm"];
        }
        // 当年 && 当天之外的时间(即昨天及以前的时间)
        else {
            // 昨天(以“现在”的时候为基准-1天)
            NSDate *yesterdayDate = [NSDate date];
            yesterdayDate = [NSDate dateWithTimeInterval:-24*60*60 sinceDate:yesterdayDate];
            
            NSDateComponents *yesterdayComponents = [calendar components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay fromDate:yesterdayDate];
            NSInteger yesterdayMonth=[yesterdayComponents month];
            NSInteger yesterdayDay=[yesterdayComponents day];
            
            // 前天(以“现在”的时候为基准-2天)
            NSDate *beforeYesterdayDate = [NSDate date];
            beforeYesterdayDate = [NSDate dateWithTimeInterval:-48*60*60 sinceDate:beforeYesterdayDate];

            NSDateComponents *beforeYesterdayComponents = [calendar components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay fromDate:beforeYesterdayDate];
            NSInteger beforeYesterdayMonth=[beforeYesterdayComponents month];
            NSInteger beforeYesterdayDay=[beforeYesterdayComponents day];
            
            // 用目标日期的“月”和“天”跟上方计算出来的“昨天”进行比较,是最为准确的(如果用时间戳差值
            // 的形式,是不准确的,比如:现在时刻是2019年02月22日1:00、而srcDate是2019年02月21日23:00,
            // 这两者间只相差2小时,直接用“delta/3600” > 24小时来判断是否昨天,就完全是扯蛋的逻辑了)
            if(srcMonth == yesterdayMonth && srcDay == yesterdayDay)
                ret = [NSString stringWithFormat:@"昨天%@", timeExtraStr];// -1d
            // “前天”判断逻辑同上
            else if(srcMonth == beforeYesterdayMonth && srcDay == beforeYesterdayDay)
                ret = [NSString stringWithFormat:@"前天%@", timeExtraStr];// -2d
            else{
                // 跟当前时间相差的小时数
                long deltaHour = (delta/3600);
                
                // 如果小于或等 7*24小时就显示星期几
                if (deltaHour <= 7*24){
                    NSArray<NSString *> *weekdayAry = [NSArray arrayWithObjects:@"星期日", @"星期一", @"星期二", @"星期三", @"星期四", @"星期五", @"星期六", nil];
                    // 取出的星期数:1表示星期天,2表示星期一,3表示星期二。。。。 6表示星期五,7表示星期六
                    NSInteger srcWeekday=[srcComponents weekday]; 

                    // 取出当前是星期几
                    NSString *weedayDesc = [weekdayAry objectAtIndex:(srcWeekday-1)];
                    ret = [NSString stringWithFormat:@"%@%@", weedayDesc, timeExtraStr];
                }
                // 否则直接显示完整日期时间
                else
                    ret = [NSString stringWithFormat:@"%@%@", [TimeTool getTimeString:dt format:@"yyyy/M/d"], timeExtraStr];
            }
        }
    }
    // 往年
    else{
        ret = [NSString stringWithFormat:@"%@%@", [TimeTool getTimeString:dt format:@"yyyy/M/d"], timeExtraStr];
    }
    
    return ret;
}

+ (NSString *)getTimeString:(NSDate *)dt format:(NSString *)fmt{
    NSDateFormatter* format = [[NSDateFormatter alloc] init];
    [format setDateFormat:fmt];
    return [format stringFromDate:(dt==nil?[TimeTool getIOSDefaultDate]:dt)];
}

+ (NSTimeInterval) getIOSTimeStamp:(NSDate *)dat{
    NSTimeInterval a = [dat timeIntervalSince1970];
    return a;
}

+ (long) getIOSTimeStamp_l:(NSDate *)dat{
    return [[NSNumber numberWithDouble:[TimeTool getIOSTimeStamp:dat]] longValue];
}

+ (NSDate*)getIOSDefaultDate
{
    return [NSDate date];
}
@end

6.2调用示例

// 用于首页“消息”界面时
[TimeTool getTimeStringAutoShort2:[NSDate date] mustIncludeTime:NO];

6.3运行效果


WX20190223-102809@2x.jpg
▲ 上述代码在RainbowChat iOS版上的运行效果(首页)

7、Web网页端的代码实现(JavaScript)


7.1完整源码


/**
* 对Date的扩展,将 Date 转化为指定格式的String。
*
*  月(M)、日(d)、小时(h)、分(m)、秒(s)、季度(q) 可以用 1-2 个占位符,
*  年(y)可以用 1-4 个占位符,毫秒(S)只能用 1 个占位符(是 1-3 位的数字)。
*
*  【示例】:
*  common.formatDate(new Date(), 'yyyy-MM-dd hh:mm:ss.S') ==> 2006-07-02 08:09:04.423
*  common.formatDate(new Date(), 'yyyy-M-d h:m:s.S')      ==> 2006-7-2 8:9:4.18
*  common.formatDate(new Date(), 'hh:mm:ss.S')            ==> 08:09:04.423
*  
*  @author 即时通讯网([url=http://www.52im.net]http://www.52im.net[/url])
*/
var _formatDate = function (date, fmt) {
        var o = {
                "M+": date.getMonth() + 1, //月份
                "d+": date.getDate(), //日
                "h+": date.getHours(), //小时
                "m+": date.getMinutes(), //分
                "s+": date.getSeconds(), //秒
                "q+": Math.floor((date.getMonth() + 3) / 3), //季度
                "S": date.getMilliseconds() //毫秒
        };
        if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length));
        for (var k in o)
                if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
                        return fmt;
};

/**
* 仿照微信中的消息时间显示逻辑,将时间戳(单位:毫秒)转换为友好的显示格式.
*
* 1)7天之内的日期显示逻辑是:今天、昨天(-1d)、前天(-2d)、星期?(只显示总计7天之内的星期数,即<=-4d);
* 2)7天之外(即>7天)的逻辑:直接显示完整日期时间。
*
* @param  {[long]} timestamp 时间戳(单位:毫秒),形如:1550789954260
* @param {boolean} mustIncludeTime true表示输出的格式里一定会包含“时间:分钟”
* ,否则不包含(参考微信,不包含时分的情况,用于首页“消息”中显示时)
*
* @return {string} 输出格式形如:“刚刚”、“10:30”、“昨天 12:04”、“前天 20:51”、“星期二”、“2019/2/21 12:09”等形式
* @author 即时通讯网([url=http://www.52im.net]http://www.52im.net[/url])
* @since 1.1
*/
var _getTimeStringAutoShort2 = function(timestamp, mustIncludeTime){

        // 当前时间
        var currentDate = new Date();
        // 目标判断时间
        var srcDate = new Date(parseInt(timestamp));

        var currentYear = currentDate.getFullYear();
        var currentMonth = (currentDate.getMonth()+1);
        var currentDateD = currentDate.getDate();

        var srcYear = srcDate.getFullYear();
        var srcMonth = (srcDate.getMonth()+1);
        var srcDateD = srcDate.getDate();

        var ret = "";

        // 要额外显示的时间分钟
        var timeExtraStr = (mustIncludeTime?" "+_formatDate(srcDate, "hh:mm"):"");

        // 当年
        if(currentYear == srcYear) {
                var currentTimestamp = currentDate.getTime();
                var srcTimestamp = timestamp;
                // 相差时间(单位:毫秒)
                var deltaTime = (currentTimestamp-srcTimestamp);

                // 当天(月份和日期一致才是)
                if(currentMonth == srcMonth && currentDateD == srcDateD) {
                // 时间相差60秒以内
                if(deltaTime < 60 * 1000)
                        ret = "刚刚";
                // 否则当天其它时间段的,直接显示“时:分”的形式
                else
                        ret = _formatDate(srcDate, "hh:mm");
                }
                // 当年 && 当天之外的时间(即昨天及以前的时间)
                else {
                        // 昨天(以“现在”的时候为基准-1天)
                        var yesterdayDate = new Date();
                        yesterdayDate.setDate(yesterdayDate.getDate()-1);

                        // 前天(以“现在”的时候为基准-2天)
                        var beforeYesterdayDate = new Date();
                        beforeYesterdayDate.setDate(beforeYesterdayDate.getDate()-2);

                        // 用目标日期的“月”和“天”跟上方计算出来的“昨天”进行比较,是最为准确的(如果用时间戳差值
                        // 的形式,是不准确的,比如:现在时刻是2019年02月22日1:00、而srcDate是2019年02月21日23:00,
                        // 这两者间只相差2小时,直接用“deltaTime/(3600 * 1000)” > 24小时来判断是否昨天,就完全是扯蛋的逻辑了)
                        if(srcMonth == (yesterdayDate.getMonth()+1) && srcDateD == yesterdayDate.getDate())
                                ret = "昨天"+timeExtraStr;// -1d
                        // “前天”判断逻辑同上
                        else if(srcMonth == (beforeYesterdayDate.getMonth()+1) && srcDateD == beforeYesterdayDate.getDate())
                                ret = "前天"+timeExtraStr;// -2d
                        else{
                                // 跟当前时间相差的小时数
                                var deltaHour = (deltaTime/(3600 * 1000));

                                // 如果小于或等 7*24小时就显示星期几
                                if (deltaHour <= 7*24){
                                var weekday=new Array(7);
                                weekday[0]="星期日";
                                weekday[1]="星期一";
                                weekday[2]="星期二";
                                weekday[3]="星期三";
                                weekday[4]="星期四";
                                weekday[5]="星期五";
                                weekday[6]="星期六";

                                // 取出当前是星期几
                                var weedayDesc = weekday[srcDate.getDay()];
                                ret = weedayDesc+timeExtraStr;
                                }
                                // 否则直接显示完整日期时间
                                else
                                ret = _formatDate(srcDate, "yyyy/M/d")+timeExtraStr;
                        }
                }
        }
        // 往年
        else{
                ret = _formatDate(srcDate, "yyyy/M/d")+timeExtraStr;
        }

        return ret;
};

7.2调用示例

// 用于首页“消息”界面时
_getTimeStringAutoShort2(1550789954260, false);
// 用于聊天内容界面时
_getTimeStringAutoShort2(1550789954260, true);

7.3运行效果


1.jpg
▲ 上述代码在RainbowChat-Web产品上的运行效果

附录:全站精品资源下载


[1] 精品源码下载:
Java NIO基础视频教程、MINA视频教程、Netty快速入门视频 [有源码]
轻量级即时通讯框架MobileIMSDK的iOS源码(开源版)[附件下载]
开源IM工程“蘑菇街TeamTalk”2015年5月前未删减版完整代码 [附件下载]
微信本地数据库破解版(含iOS、Android),仅供学习研究 [附件下载]
NIO框架入门(四):Android与MINA2、Netty4的跨平台UDP双向通信实战 [附件下载]
NIO框架入门(三):iOS与MINA2、Netty4的跨平台UDP双向通信实战 [附件下载]
NIO框架入门(二):服务端基于MINA2的UDP双向通信Demo演示 [附件下载]
NIO框架入门(一):服务端基于Netty4的UDP双向通信Demo演示 [附件下载]
用于IM中图片压缩的Android工具类源码,效果可媲美微信 [附件下载]
高仿Android版手机QQ可拖拽未读数小气泡源码 [附件下载]
一个WebSocket实时聊天室Demo:基于node.js+socket.io [附件下载]
Android聊天界面源码:实现了聊天气泡、表情图标(可翻页) [附件下载]
高仿Android版手机QQ首页侧滑菜单源码 [附件下载]
开源libco库:单机千万连接、支撑微信8亿用户的后台框架基石 [源码下载]
分享java AMR音频文件合并源码,全网最全
微信团队原创Android资源混淆工具:AndResGuard [有源码]
一个基于MQTT通信协议的完整Android推送Demo [附件下载]
Android版高仿微信聊天界面源码 [附件下载]
高仿手机QQ的Android版锁屏聊天消息提醒功能 [附件下载]
高仿iOS版手机QQ录音及振幅动画完整实现 [源码下载]
Android端社交应用中的评论和回复功能实战分享[图文+源码]
Android端IM应用中的@人功能实现:仿微博、QQ、微信,零入侵、高可扩展[图文+源码]
仿微信的IM聊天时间显示格式(含iOS/Android/Web实现源码)[图文+源码]

[2] 精品文档和工具下载:
计算机网络通讯协议关系图(中文珍藏版)[附件下载]
史上最全即时通讯软件简史(精编大图版)[附件下载]
重磅发布:《阿里巴巴Android开发手册(规约)》[附件下载]
阿里技术结晶:《阿里巴巴Java开发手册(规约)-终极版》[附件下载]
基于RTMP协议的流媒体技术的原理与应用(技术论文)[附件下载]
独家发布《TCP/IP详解 卷1:协议》CHM版 [附件下载]
良心分享:WebRTC 零基础开发者教程(中文)[附件下载]
MQTT协议手册(中文翻译版)[附件下载]
经典书籍《UNIX网络编程》最全下载(卷1+卷2、中文版+英文版)[附件下载]
音视频开发理论入门书籍之《视频技术手册(第5版)》[附件下载]
国际电联H.264视频编码标准官方技术手册(中文版)[附件下载]
Apache MINA2.0 开发指南(中文版)[附件下载]
网络通讯数据抓包和分析工具 Wireshark 使用教程(中文) [附件下载]
最新收集NAT穿越(p2p打洞)免费STUN服务器列表 [附件下载]
高性能网络编程经典:《The C10K problem(英文)》[附件下载]
即时通讯系统的原理、技术和应用(技术论文)[附件下载]
技术论文:微信对网络影响的技术试验及分析[附件下载]
华为内部3G网络资料: WCDMA系统原理培训手册[附件下载]
网络测试:Android版多路ping命令工具EnterprisePing[附件下载]
Android反编译利器APKDB:没有美工的日子里继续坚强的撸
一款用于P2P开发的NAT类型检测工具 [附件下载]
两款增强型Ping工具:持续统计、图形化展式网络状况 [附件下载]

[3] 精选视频、演讲PPT下载:
美图海量用户的IM架构零基础演进之路(PPT)[附件下载]
开源实时音视频工程WebRTC的架构详解与实践总结(PPT+视频)[附件下载]
QQ空间百亿级流量的社交广告系统架构实践(视频+PPT)[附件下载]
海量实时消息的视频直播系统架构演进之路(视频+PPT)[附件下载]
YY直播在移动弱网环境下的深度优化实践分享(视频+PPT)[附件下载]
QQ空间移动端10亿级视频播放技术优化揭秘(视频+PPT)[附件下载]
RTC实时互联网2017年度大会精选演讲PPT [附件下载]
微信分享开源IM网络层组件库Mars的技术实现(视频+PPT)[附件下载]
微服务理念在微信海量用户后台架构中的实践(视频+PPT)[附件下载]
移动端IM开发和构建中的技术难点实践分享(视频+PPT)[附件下载]
网易云信的高品质即时通讯技术实践之路(视频+PPT)[附件下载]
腾讯音视频实验室:直面音视频质量评估之痛(视频+PPT)[附件下载]
腾讯QQ1.4亿在线用户的技术挑战和架构演进之路PPT[附件下载]
微信朋友圈海量技术之道PPT[附件下载]
手机淘宝消息推送系统的架构与实践(音频+PPT)[附件下载]
如何进行实时音视频的质量评估与监控(视频+PPT)[附件下载]
Go语言构建高并发消息推送系统实践PPT(来自360公司)[附件下载]
网易IM云千万级并发消息处理能力的架构设计与实践PPT [附件下载]
手机QQ的海量用户移动化实践分享(视频+PPT)[附件下载]
钉钉——基于IM技术的新一代企业OA平台的技术挑战(视频+PPT)[附件下载]
微信技术总监谈架构:微信之道——大道至简(PPT讲稿)[附件下载]
Netty的架构剖析及应用案例介绍(视频+PPT)[附件下载]
声网架构师谈实时音视频云的实现难点(视频采访)
滴滴打车架构演变及应用实践(PPT讲稿)[附件下载]
微信海量用户背后的后台系统存储架构(视频+PPT)[附件下载]
在线音视频直播室服务端架构最佳实践(视频+PPT)[附件下载]
从0到1:万人在线的实时音视频直播技术实践分享(视频+PPT)[附件下载]
微信移动端应对弱网络情况的探索和实践PPT[附件下载]
Android版微信从300KB到30MB的技术演进(PPT讲稿)[附件下载]
从零开始搭建瓜子二手车IM系统(PPT)[附件下载]
极光分享:高并发海量消息推送系统架构演进(视频+PPT)[附件下载]

即时通讯网 - 即时通讯开发者社区! 来源: - 即时通讯开发者社区!

上一篇:Android端IM应用中的@人功能实现:仿微博、QQ、微信,零入侵、高可扩展[图文+源码]

本帖已收录至以下技术专辑

推荐方案
打赏楼主 ×
使用微信打赏! 使用支付宝打赏!

返回顶部