需求背景
因为经常需要把手机的图片展示到电视上,以前的操作都是把图片放在U盘里,然后插在电视usb接口上,操作比较繁琐,所以选择使用局域网传输文件的方式来完成这个需求。开始的时候是准备使用socket来完成这个需求,考虑到可能有多台设备上传图片或者一台设备上传多张图片的处理比较麻烦,便去网上找开源的框架来解决这个问题,于是找到了androidasync这个框架。
androidasync使用
androidasync项目地址
添加依赖
compile 'com.koushikdutta.async:androidasync:2.+'
创建AsyncHttpServer对象
AsyncHttpServer mServer = new AsyncHttpServer();
AsyncServer mAsyncServer = new AsyncServer();`
这里的AsyncHttpServer 可以理解为我们平常使用的tomcat,我们可以通过这个对象,在android设备里部署一个自己的服务器,这也是AndroidAsync框架的强大之处,他把我们以前繁琐的局域网操作简化成普通的网络访问操作,通过创建AsyncHttpServer对象,可以暴露出一系列接口,供局域网的其他设备去访问,接口创建形式如下如下:
mServer.get("/test", new HttpServerRequestCallback() {
@Override
public void onRequest(AsyncHttpServerRequest request, AsyncHttpServerResponse response) {
response.send("ok");
}
});
//监听指定端口
mServer.listen(54321);
在电视上运行demo,然后在电脑浏览器输入以下地址 http://192.168.3.201:54321/test这里的192.168.3.201是我设备的地址,54321是我在上述代码里指定的端口号,可以看到在浏览器上会输出我们在代码里返回的内容:
image.png是不是很神奇,以前做局域网通信的时候总是要服务端创建一个socket客户端一个socket而且这样的话,还只能在两台android设备间通信,如果说要想实现这种在浏览器也能访问,我没试过但应该难度不小,接下来就开始完成我们的需求,接收客户端上传的文件并进行展示。
File mFile= new File(externalStorageDirectory, "test");
mServer.post("/upload", new HttpServerRequestCallback() {
@Override
public void onRequest(AsyncHttpServerRequest request, final AsyncHttpServerResponse response) {
if (!mFile.exists() || !mFile.isDirectory()) {
mFile.mkdirs();
}
mBody = (MultipartFormDataBody) request.getBody();
mBody.setMultipartCallback(new MultipartFormDataBody.MultipartCallback() {
@Override
public void onPart(final Part part) {
//每次上传文件,这个回调至少执行一次,执行次数取决于上传文件次数
if (part.isFile()) {
//创建文件,用于写入上传的图片
String s = System.currentTimeMillis() + part.getFilename();
File cache_file = new File(mFile.getAbsolutePath(), s);
try {
//因为方法多次执行,所以判断不为空就关闭流
if (mFileOutputStream != null) {
mFileOutputStream.close();
}
mFileOutputStream = new FileOutputStream(cache_file);
} catch (Exception e) {
e.printStackTrace();
}
mBody.setDataCallback(new DataCallback() {
@Override
public void onDataAvailable(DataEmitter emitter, ByteBufferList bb) {
//每接收一次文件,这个回调至少执行一次,执行次数不固定,取决于上传的单个文件的大小,所以不要以为这个方法执行了,就代表文件已经上传结束了,是否结束取决于上面的onPart是否再次执行
byte[] allByteArray = bb.getAllByteArray();
try {
mFileOutputStream.write(allByteArray, 0, allByteArray.length);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
});
request.setEndCallback(new CompletedCallback() {
@Override
public void onCompleted(Exception ex) {
try {
//文件上传结束,在这里可以直接用glide就可以加载我们保存在本地的图片了
if (mFileOutputStream != null) {
mFileOutputStream.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
});
运行程序,用postman测试:
image.png
运行效果如下:
image.png
既然用postman能上传成功,那客户端自己采用合适的网络框架也可以成功上传文件了。至此,使用androidasync在局域网操作文件的流程就结束了,在这里可以看到这个框架在局域网通信的便捷之处,androidasync也提供了一系列其他的局域网长链接操作,有感兴趣的朋友可以去尝试一下,如果有写错的地方也请各位指教。谢谢
网友评论