java 友好时间显示_仿微信的IM聊天时间显示格式(含iOS/Android/Web实现)[图文+源码]...

本文为原创分享,转载请注明出处。

1、引言

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

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

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

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

学习交流:- 即时通讯/推送技术开发交流4群:101279154 [推荐]

- 移动端IM开发入门文章:《新手入门一篇就够:从零开发移动端IM》

2、相关文章

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

先来看看微信中聊天消息的时间显示成什么样:微信主页“消息”界面

聊天界面(注意聊天界面中默认带了“时:分”的显示)

来自微信官方对聊天消息时间显示的规则说明:

▲ 该规则的定义,主要是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])

*/

publicstaticString getTimeString(Date dt, String pattern)

{

try

{

SimpleDateFormat sdf = newSimpleDateFormat(pattern);//"yyyy-MM-dd HH:mm:ss"

sdf.setTimeZone(TimeZone.getDefault());

returnsdf.format(dt);

}

catch(Exception e)

{

return"";

}

}

/**

* 仿照微信中的消息时间显示逻辑,将时间戳(单位:毫秒)转换为友好的显示格式.

*

* 1)7天之内的日期显示逻辑是:今天、昨天(-1d)、前天(-2d)、星期?(只显示总计7天之内的星期数,即<=-4d);

* 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

*/

publicstaticString getTimeStringAutoShort2(Date srcDate, booleanmustIncludeTime)

{

String ret = "";

try

{

GregorianCalendar gcCurrent = newGregorianCalendar();

gcCurrent.setTime(newDate());

intcurrentYear = gcCurrent.get(GregorianCalendar.YEAR);

intcurrentMonth = gcCurrent.get(GregorianCalendar.MONTH)+1;

intcurrentDay = gcCurrent.get(GregorianCalendar.DAY_OF_MONTH);

GregorianCalendar gcSrc = newGregorianCalendar();

gcSrc.setTime(srcDate);

intsrcYear = gcSrc.get(GregorianCalendar.YEAR);

intsrcMonth = gcSrc.get(GregorianCalendar.MONTH)+1;

intsrcDay = gcSrc.get(GregorianCalendar.DAY_OF_MONTH);

// 要额外显示的时间分钟

String timeExtraStr = (mustIncludeTime?" "+getTimeString(srcDate, "HH:mm"):"");

// 当年

if(currentYear == srcYear)

{

longcurrentTimestamp = gcCurrent.getTimeInMillis();

longsrcTimestamp = gcSrc.getTimeInMillis();

// 相差时间(单位:毫秒)

longdelta = (currentTimestamp - srcTimestamp);

// 当天(月份和日期一致才是)

if(currentMonth == srcMonth && currentDay == srcDay)

{

// 时间相差60秒以内

if(delta < 60* 1000)

ret = "刚刚";

// 否则当天其它时间段的,直接显示“时:分”的形式

else

ret = getTimeString(srcDate, "HH:mm");

}

// 当年 && 当天之外的时间(即昨天及以前的时间)

else

{

// 昨天(以“现在”的时候为基准-1天)

GregorianCalendar yesterdayDate = newGregorianCalendar();

yesterdayDate.add(GregorianCalendar.DAY_OF_MONTH, -1);

// 前天(以“现在”的时候为基准-2天)

GregorianCalendar beforeYesterdayDate = newGregorianCalendar();

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

}

// “前天”判断逻辑同上

elseif(srcMonth == (beforeYesterdayDate.get(GregorianCalendar.MONTH)+1)

&& srcDay == beforeYesterdayDate.get(GregorianCalendar.DAY_OF_MONTH))

{

ret = "前天"+timeExtraStr;// -2d

}

else

{

// 跟当前时间相差的小时数

longdeltaHour = (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】");

}

returnret;

}

5.2 调用示例// 用于首页“消息”界面时

getTimeStringAutoShort2(newDate(), false);

// 用于聊天内容界面时

getTimeStringAutoShort2(newDate(), true);

5.3 运行效果

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

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

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

6.1 完整源码

源文件TimeTool.h:#import

@interfaceTimeTool : 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;

@end

源文件TimeTool.m:#import "TimeTool.h"

@implementationTimeTool

// 仿照微信的逻辑,显示一个人性化的时间字串

+ (NSString*)getTimeStringAutoShort2:(NSDate*)dt mustIncludeTime:(BOOL)includeTime{

NSString*ret = nil;

NSCalendar*calendar = [NSCalendarcurrentCalendar];

// 当前时间

NSDate*currentDate = [NSDatedate];

NSDateComponents*curComponents = [calendar components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay|NSCalendarUnitWeekdayfromDate:currentDate];

NSIntegercurrentYear=[curComponents year];

NSIntegercurrentMonth=[curComponents month];

NSIntegercurrentDay=[curComponents day];

// 目标判断时间

NSDateComponents*srcComponents = [calendar components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay|NSCalendarUnitWeekdayfromDate:dt];

NSIntegersrcYear=[srcComponents year];

NSIntegersrcMonth=[srcComponents month];

NSIntegersrcDay=[srcComponents day];

// 要额外显示的时间分钟

NSString*timeExtraStr = (includeTime?[TimeTool getTimeString:dt format:@" HH:mm"]:@"");

// 当年

if(currentYear == srcYear) {

longcurrentTimestamp = [TimeTool getIOSTimeStamp_l:currentDate];

longsrcTimestamp = [TimeTool getIOSTimeStamp_l:dt];

// 相差时间(单位:秒)

longdelta = currentTimestamp - srcTimestamp;

// 当天(月份和日期一致才是)

if(currentMonth == srcMonth && currentDay == srcDay) {

// 时间相差60秒以内

if(delta < 60)

ret = @"刚刚";

// 否则当天其它时间段的,直接显示“时:分”的形式

else

ret = [TimeTool getTimeString:dt format:@"HH:mm"];

}

// 当年 && 当天之外的时间(即昨天及以前的时间)

else{

// 昨天(以“现在”的时候为基准-1天)

NSDate*yesterdayDate = [NSDatedate];

yesterdayDate = [NSDatedateWithTimeInterval:-24*60*60 sinceDate:yesterdayDate];

NSDateComponents*yesterdayComponents = [calendar components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDayfromDate:yesterdayDate];

NSIntegeryesterdayMonth=[yesterdayComponents month];

NSIntegeryesterdayDay=[yesterdayComponents day];

// 前天(以“现在”的时候为基准-2天)

NSDate*beforeYesterdayDate = [NSDatedate];

beforeYesterdayDate = [NSDatedateWithTimeInterval:-48*60*60 sinceDate:beforeYesterdayDate];

NSDateComponents*beforeYesterdayComponents = [calendar components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDayfromDate:beforeYesterdayDate];

NSIntegerbeforeYesterdayMonth=[beforeYesterdayComponents month];

NSIntegerbeforeYesterdayDay=[beforeYesterdayComponents day];

// 用目标日期的“月”和“天”跟上方计算出来的“昨天”进行比较,是最为准确的(如果用时间戳差值

// 的形式,是不准确的,比如:现在时刻是2019年02月22日1:00、而srcDate是2019年02月21日23:00,

// 这两者间只相差2小时,直接用“delta/3600” > 24小时来判断是否昨天,就完全是扯蛋的逻辑了)

if(srcMonth == yesterdayMonth && srcDay == yesterdayDay)

ret = [NSStringstringWithFormat:@"昨天%@", timeExtraStr];// -1d

// “前天”判断逻辑同上

elseif(srcMonth == beforeYesterdayMonth && srcDay == beforeYesterdayDay)

ret = [NSStringstringWithFormat:@"前天%@", timeExtraStr];// -2d

else{

// 跟当前时间相差的小时数

longdeltaHour = (delta/3600);

// 如果小于或等 7*24小时就显示星期几

if(deltaHour <= 7*24){

NSArray *weekdayAry = [NSArrayarrayWithObjects:@"星期日", @"星期一", @"星期二", @"星期三", @"星期四", @"星期五", @"星期六", nil];

// 取出的星期数:1表示星期天,2表示星期一,3表示星期二。。。。 6表示星期五,7表示星期六

NSIntegersrcWeekday=[srcComponents weekday];

// 取出当前是星期几

NSString*weedayDesc = [weekdayAry objectAtIndex:(srcWeekday-1)];

ret = [NSStringstringWithFormat:@"%@%@", weedayDesc, timeExtraStr];

}

// 否则直接显示完整日期时间

else

ret = [NSStringstringWithFormat:@"%@%@", [TimeTool getTimeString:dt format:@"yyyy/M/d"], timeExtraStr];

}

}

}

// 往年

else{

ret = [NSStringstringWithFormat:@"%@%@", [TimeTool getTimeString:dt format:@"yyyy/M/d"], timeExtraStr];

}

returnret;

}

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

NSDateFormatter* format = [[NSDateFormatteralloc] init];

[format setDateFormat:fmt];

return[format stringFromDate:(dt==nil?[TimeTool getIOSDefaultDate]:dt)];

}

+ (NSTimeInterval) getIOSTimeStamp:(NSDate*)dat{

NSTimeIntervala = [dat timeIntervalSince1970];

returna;

}

+ (long) getIOSTimeStamp_l:(NSDate*)dat{

return[[NSNumbernumberWithDouble:[TimeTool getIOSTimeStamp:dat]] longValue];

}

@end

6.2 调用示例// 用于首页“消息”界面时

[TimeTool getTimeStringAutoShort2:[NSDatedate] mustIncludeTime:NO];

6.3 运行效果

▲ 上述代码在RainbowChat iOS版上的运行效果(首页)

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

7.1 完整源码抱歉:因文章字数限制,JavaScript版源码无非法贴上来,请从链接:http://www.52im.net/thread-2371-1-1.html,查看JavaScript版完整源码!

7.2 调用示例// 用于首页“消息”界面时

_getTimeStringAutoShort2(1550789954260, false);

// 用于聊天内容界面时

_getTimeStringAutoShort2(1550789954260, true);

7.3 运行效果

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

附录:更多精品资源下载

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/551717.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

查看grafana版本_使用 Prometheus 与 Grafana 为 Kubernetes 集群建立监控与警报机制

作者 | Gregoire DAYET 策划 | 田晓旭 IT 团队已经明确意识到对基础设施进行监控的必要性。目前市面上存在着大量适用于传统基础设施且历史悠久的解决方案&#xff1a;Nagios、Zabbix 等工具都是其中的代表。但这些工具并不足以解决 Kubernetes 生态系统在多层级抽象与故障排查…

java的注解_java-注解相关

注解概念&#xff1a;说明程序的&#xff0c;给计算机看注释&#xff1a;用文字描述程序先了解一些怎么正常javadoc文档1&#xff1a;给类或者方法添加doc注释2&#xff1a;通过命令javadoc 执行 类.java文件新建的类&#xff1a;/*** 注解doc演示*authorquan*sincejdk 1.7*ver…

linux删除文件_Linux删除文件夹用什么命令

请关注本头条号&#xff0c;每天坚持更新原创干货技术文章。如需学习视频&#xff0c;请在微信搜索公众号“智传网优”直接开始自助视频学习1. 前言本文主要讲解Linux删除文件夹或目录的命令rmdir和rm的使用方法。Windows上的文件夹与Linux系统里的目录是同一概念。默认情况下&…

python opencv2_Python + OpenCV2 系列:2 - 图片操作

这些相当于我的学习笔记&#xff0c;所以并没有很强的结构性和很全的介绍&#xff0c;请见谅。1. 读取/写入图像下面是一个简短的载入图像、打印尺寸、转换格式及保存图像为.png的例子&#xff1a;#-*- coding: utf-8 -*-importcv2import numpy as np#读入图像im cv2.imread(.…

java core 生成路径_core文件生成和路径设置

在程序崩溃时&#xff0c;内核会生成一个core文件,即程序最后崩溃时的内存映像&#xff0c;和程序调试信息。 之后可以通过gdb,打开core文件察看程序崩溃时的堆栈信息&#xff0c;可以找出程序出错的代码所在文件和函数。1.core文件的生成开关和大小限制 1)使用ulimit -a命令&…

shrio 登陆后 还是失效_在 iPhone 上取消订阅后,应用或内容会立即失效吗?

在 iPhone 中&#xff0c;一些应用和服务需要进行订阅&#xff0c;即您需要支付相应的费用以获得应用或服务中内容的访问权限。如果您想要取消订阅某个项目&#xff0c;可以按以下步骤操作&#xff1a;前往 iPhone “设置”-“Apple ID”-“iTunes Store 与 App Store”&#x…

java可以返回微妙吗_Java开发中10个最为微妙的最佳编程实践

这是10个最佳实践的列表&#xff0c;比你平时在Josh Bloch的《effective java》中看到的规则更加精妙。和Josh Bloch列出的非常容易学习的、和日常情况息息相关的实践相比&#xff0c;这个列表中提到了一些关于设计API/SPI的实践&#xff0c;虽然不常见&#xff0c;但是存在很大…

python3.7输出语句_Day3-Python-Python字符串if语句学习-2018/7/18

1.什么是字符串a.使用单引号或者双引号括起来的字符集就是字符串。b.引号中单独的符号、数字、字母等叫字符c.转义字符&#xff1a;可以用来表示一些有特殊功能或是特殊意义的字符(通过在固定的字符前加反斜杠\)\->\\->\\n->换行\t->制表符\"->"在计算…

wifi 信道_WiFi网速太慢,四招就可以让无线网络变得顺畅

和WIFI网速相关联的因素主要有四个&#xff0c;对应解决方法也就有四个。频段冲突是WIFI网速变慢很常见的问题。现实中常用的WIFI频段有2.4GHZ和5GHZ两个大频段&#xff0c;也好比两条高速公路。中国2.4GHZ频段里有11个信道&#xff0c;5GHZ有15个信道。多少个信道就好比有多少…

判读一个对象不为空_“人不为己,天诛地灭”的真实含义

“人不为己&#xff0c;天诛地灭”出自《佛说十善业道经》&#xff0c;其意思不是“一个人如果不为自己谋利益&#xff0c;就会遭到天地诛灭”&#xff0c;而是“一个人如果不修行自己的德行&#xff0c;那么就会为天地所不容”。“为”是修习、修炼、修行的意思&#xff0c;修…

java https双向验证_java https双向认证证书

// 双向认证证书KeyStore keyStore KeyStore.getInstance(“PKCS12”);KeyStore trustStore KeyStore.getInstance(“jks”);// keyStore是服务端验证客户端的证书&#xff0c;trustStore是客户端的信任证书InputStream ksIn new FileInputStream(“E:/Java/jre8/lib/securi…

c++opencv显示中文_OpenCV如何入门秘籍

OpenCV简介谈起入门&#xff0c;我们首先要搞明白OpenCV是什么&#xff1f;OpenCV的全称是Open Source Computer Vision Library&#xff0c;是一种计算机视觉库&#xff0c;主要用于处理摄像头采集的图像。既然说到了是一种库&#xff0c;就要聊聊这个库使用什么语言编写的。O…

安卓开发文档_鸿蒙2.0,HarmonyOS开发体验!

“没有人能够熄灭漫天星光”。在9月10日的华为2020开发者大会上&#xff0c;余承东掷地有声地说道。从去年开放的鸿蒙1.0&#xff0c;到今年的2.0。仅仅一年时间&#xff0c;华为就把基础设施全部搭建好。从之前的感知不强&#xff0c;到现在的触手可得&#xff0c;让果核这个半…

吉比特java开发_JVM 吉比特后台 Java 开发实习生 20 分钟一轮游 _好机友

吉比特后台 Java 开发实习生 20 分钟一轮游作者&#xff1a;胖若两人链接&#xff1a;https://www.nowcoder.com/discuss/155198?type2&order3&pos9&page1来源&#xff1a;牛客网关于在牛客前几天投的&#xff0c;就在今天早上&#xff0c;面了 20 分钟就结束了&a…

python字符串类型_Python3的字符串类型(疯狂Python)

先看一下本篇文章要讲的内容目录&#xff1a; 4.2 字符串入门String4.2.1 repr和字符串4.2.2 input和raw_input4.2.3 长字符串4.2.4 bytes4.2.5 字符串格式化4.2.6 Python自带两个帮助函数4.2.7 删除多余空白4.2.8 字符串的查找&#xff0c;替换4.2.9 字符串的分割&#xff0c;…

盘点苹果微信聊天记录恢复的3大常用方法!

微信聊天记录一旦被误删除或者意外丢失&#xff0c;那确实是一件麻烦的事情。如果只是丢失了文件、图片、视频等&#xff0c;那么重新让好友转发就行。 那如果是想恢复全部聊天记录呢&#xff1f;苹果微信聊天记录恢复有哪些方法&#xff1f;如果你还不知道正确的恢复方法&…

php 修改文件属性命令,php:修改目录下文档权限(777,644 )

php&#xff1a;修改目录下文档权限(777&#xff0c;644 )文章分类:PHP编程PHP chmod() 函数 (upload image permit)PHP Filesystem 函数定义和用法chmod() 函数改变文件模式。如果成功则返回 TRUE&#xff0c;否则返回 FALSE。语法chmod(file,mode)参数描述file必需。规定要检…

python采用面向对象编程模式吗_如何理解 Python 中的面向对象编程?

现如今面向对象编程的使用非常广泛&#xff0c;本文我们就来探讨一下Python中的面向对象编程。作者 | Radek Fabisiak 译者 | 弯月&#xff0c;责编 | 郭芮 以下为译文&#xff1a; Python支持多种类型的编程范式&#xff0c;例如过程式编程、函数式编程、面向对象编程&#xf…

上传文件的php代码,PHP实现大文件上传源代码

PHP实现大文件上传源代码PHP 基础教程 PHP 是一种创建动态交互性站点的强有力的服务器端脚本语言。 PHP 是免费的&#xff0c;并且使用广泛。 以下是小编为大家搜索整理的PHP实现大文件上传源代码&#xff0c;希望能给大家带来帮助!更多精彩内容请及时关注我们应届毕业生考试!经…

android 打开系统相册_这5款常用Android手机自动化测试工具你要收藏

1、Monkey是Android SDK自带的测试工具&#xff0c;在测试过程中会向系统发送伪随机的用户事件流&#xff0c;如按键输入、触摸屏输入、手势输入等)&#xff0c;实现对正在开发的应用程序进行压力测试&#xff0c;也有日志输出。实际上该工具只能做程序做一些压力测试&#xff…