Xutil框架相信很多Android开发程序员都不陌生,Xutil集注解、网络、图片加载、数据库操作与一身的Android端框架,更新的Xutil3更简单的方便,在这里不针对Xutil的中心内容进行讲解,主要讲在使用Xutil中发现的问题。

一、Xutil中0B文件无法下载问题

      由于公司需要,对于文件下载、上传等需要对0B文件也做到兼容,但是后期测试发现Xutil3在下载0B文件后直接抛出了异常,具体的抛错地方如下。





   
 如果文件下载正常的话,我们下载一个文件的执行顺序如下(正常情况下):onWaiting-->onStarted-->onLoading-->onSuccess-->onFinished。正常的情况下是这样的,但是在下载0B文件时,意想不到的是执行完onStarted后,直接进入了onError方法,错误如下,竟然提示没有Cache
file not found???



   
对于0B文件下载的出错的处理,这里我偷了个懒,没有深入研究为什么抛出这个异常,而是在它回调到onError时,再进行进一步的判断,使用最基础的HttpURLConnection的方法上传,暂时处理一下这个问题(待深入-_-),具体代码如下。
/** * 从网络Url中下载文件 * * @param urlStr * @param savePath * @throws IOException
*/ private void downLoadFromUrl(String urlStr, String savePath) { new Thread(){
@Override public void run() { super.run(); FileOutputStream fos = null;
InputStream inputStream = null; try { URL url = new URL(urlStr);
HttpURLConnection conn = (HttpURLConnection) url.openConnection(); //设置超时间为3秒
conn.setConnectTimeout(3 * 1000); //防止屏蔽程序抓取而返回403错误
conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0;
Windows NT; DigExt)"); //得到输入流 inputStream = conn.getInputStream(); //获取自己数组
byte[] getData = readInputStream(inputStream); //文件保存位置 File saveDir = new
File(savePath); if (!saveDir.getParentFile().exists()) {
saveDir.getParentFile().mkdir(); } File file = new File(savePath); fos = new
FileOutputStream(file); fos.write(getData); //TODO: 这里实现你上传成功需要处理的逻辑
LogUtil.i("info:" + url + " download success"); }catch (IOException ex){
ex.printStackTrace(); LogUtil.e(ex.getMessage()); //TODO:这里是一个简单错误日志异常上报 new
LogApi().uploadLog("downLoadFromUrl" , DownloadCallback.class.getSimpleName() ,
"try catch;" + ex.toString() + "ex.message:" + ex.getMessage() + ";" +
"downloadInfo:" + downloadInfo.toString() + ";" , 1); //TODO: 这里实现你上传失败需要处理的逻辑
}finally { try { if (fos != null) { fos.close(); } if (inputStream != null) {
inputStream.close(); } }catch (IOException ex){ ex.printStackTrace();
LogUtil.e(ex.getMessage()); new LogApi().uploadLog("downLoadFromUrl" ,
DownloadCallback.class.getSimpleName() , "try catch finish;" + ex.toString() +
"ex.message:" + ex.getMessage() + ";" + "downloadInfo:" +
downloadInfo.toString() + ";" , 1); //TODO: 这里实现你上传失败需要处理的逻辑 } } } }.start(); }
/** * 从输入流中获取字节数组 * * @param inputStream * @return * @throws IOException */
public byte[] readInputStream(InputStream inputStream) throws IOException {
byte[] buffer = new byte[1024]; int len = 0; ByteArrayOutputStream bos = new
ByteArrayOutputStream(); while ((len = inputStream.read(buffer)) != -1) {
bos.write(buffer, 0, len); } bos.close(); return bos.toByteArray(); }
二、Xutil3中0B无法上传

   
上一个问题,发现0B文件无法下载,测试上传时???,竟然直接出现红点,说上传错误,经过作者不懈努力的查找,终于发现了问题所在。原来Xutil3在添加上传文件的Body时使用到的MultipartBody中,初始化其中的CounterOutputStream时,调用其中的方法addStream,具体如下。>0????,猜到同仁们知道怎么改了吧,改成>=0,就可以上传了。修改的具体代码在MultipartBody-->CounterOutputStream-->addStream
public void addStream(InputStream inputStream) { if (total.get() == -1L)
return; long length = InputStreamBody.getInputStreamLength(inputStream);
//没错,就是这里>0????????? if (length > 0) { total.addAndGet(length); } else {
total.set(-1L); } }
三、Xutils3下载、上传大于2G文件异常 

   
此问题,具体表现,如下在下载2G文件时,它的onLoading竟然不调用。。。但是它一直在使用你的网络,如果你重新暂停以后再开始他又会调用了,但是进度会出现问题,一直百分之百。。。这个问题引发的原因,作者找了下,2G这个间隔是不是有点熟悉?没错,就是int类型的最大的取值范围,在框架内的具体体现,看官们请看下面具体代码。

    (1)FileLoader-->load(UriRequest)



     (2)HttpRequest 



    (3)URLConnection 



     (4)FileLoader-->load(UriRequest)



    (5)HttpTask 

 

   
 上面几张图循序渐进,图一是针对于contentLength初始化,进入到图二、图三是具体调用的方法,看到图三,发现没有2G以上这里默认,返回的是-1,但是图四是整体控制onLoading的方法,>-1才执行(忘记具体代码,但是-1是绝对不会继续执行的)???,修改方案看官们也懂了吧?>=-1,让它继续执行下去;这里解决了第一次不会执行onLoading的方法,但是之后又有回调了,这是为什么呢?原来使我们设置了断点续传,会读取本地下载的长度,这个时候current的长度不为0,所以会执行onLoading的方法,但是由于那个长度溢出了,最后下载的时候onLoading中的total和current是一直相等的,这个时候如果你需要设置进度的话,你最好使用后台返回的文件大小进行设置,要不然会导致进度出现问题(如果还想改更底层,就只能对URLConnection了,由于系统已经完善,不能更改太多,暂时如此处理),如果修改了问题三的bug,这个时候你要注意total在第一次返回的时候会是0,如果有使用到就对他进行大于0的判断。
public int getContentLength() { long l = getContentLengthLong(); if (l >
Integer.MAX_VALUE) return -1; return (int) l; }
    需要修改的代码HttpTask-->updateProgress。





四、Xutils3重定向使用问题

     
这不能说是bug,只能说是使用问题,关于设置重定向问题,默认提示Xutil3是自动支持重定向的,过于相信没管它,但是测试后发现它不会自动重定向,怎么做呢?下面这样做就好。这里我是在自定义的请求中设置的,如果你只是一个实例,直接调用内部的setRedirectHandler方法就好,这里Location是需要重定向的地址。
/** * 自定义网络请求Header,携带及保存cookie * Created by yzy on 2018/4/8 10:15 */ public
class NetParams extends RequestParams { public NetParams(String uri) {
super(uri); setRedirectHandler(uriRequest -> { RequestParams requestParams =
uriRequest.getParams(); String location =
uriRequest.getResponseHeader("Location"); //协定的重定向地址
if(!StringUtils.isEmptyOrNull(location)){ requestParams.setUri(location);
//重新设置url地址 } return requestParams; }); //重定向 setMaxRetryCount(5); //重定向次数 } }
 

友情链接
KaDraw流程图
API参考文档
OK工具箱
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:[email protected]
QQ群:637538335
关注微信