需求背景
因?yàn)榻?jīng)常需要把手機(jī)的圖片展示到電視上,以前的操作都是把圖片放在U盤(pán)里,然后插在電視usb接口上,操作比較繁瑣,所以選擇使用局域網(wǎng)傳輸文件的方式來(lái)完成這個(gè)需求。開(kāi)始的時(shí)候是準(zhǔn)備使用socket來(lái)完成這個(gè)需求,考慮到可能有多臺(tái)設(shè)備上傳圖片或者一臺(tái)設(shè)備上傳多張圖片的處理比較麻煩,便去網(wǎng)上找開(kāi)源的框架來(lái)解決這個(gè)問(wèn)題,于是找到了androidasync這個(gè)框架。
androidasync使用
androidasync項(xiàng)目地址
添加依賴(lài)
compile 'com.koushikdutta.async:androidasync:2.+'
創(chuàng)建AsyncHttpServer對(duì)象
AsyncHttpServer mServer = new AsyncHttpServer();
AsyncServer mAsyncServer = new AsyncServer();`
這里的AsyncHttpServer 可以理解為我們平常使用的tomcat,我們可以通過(guò)這個(gè)對(duì)象,在android設(shè)備里部署一個(gè)自己的服務(wù)器,這也是AndroidAsync框架的強(qiáng)大之處,他把我們以前繁瑣的局域網(wǎng)操作簡(jiǎn)化成普通的網(wǎng)絡(luò)訪(fǎng)問(wèn)操作,通過(guò)創(chuàng)建AsyncHttpServer對(duì)象,可以暴露出一系列接口,供局域網(wǎng)的其他設(shè)備去訪(fǎng)問(wèn),接口創(chuàng)建形式如下如下:
mServer.get("/test", new HttpServerRequestCallback() {
@Override
public void onRequest(AsyncHttpServerRequest request, AsyncHttpServerResponse response) {
response.send("ok");
}
});
//監(jiān)聽(tīng)指定端口
mServer.listen(54321);
在電視上運(yùn)行demo,然后在電腦瀏覽器輸入以下地址 http://192.168.3.201:54321/test這里的192.168.3.201是我設(shè)備的地址,54321是我在上述代碼里指定的端口號(hào),可以看到在瀏覽器上會(huì)輸出我們?cè)诖a里返回的內(nèi)容:

是不是很神奇,以前做局域網(wǎng)通信的時(shí)候總是要服務(wù)端創(chuàng)建一個(gè)socket客戶(hù)端一個(gè)socket而且這樣的話(huà),還只能在兩臺(tái)android設(shè)備間通信,如果說(shuō)要想實(shí)現(xiàn)這種在瀏覽器也能訪(fǎng)問(wèn),我沒(méi)試過(guò)但應(yīng)該難度不小,接下來(lái)就開(kāi)始完成我們的需求,接收客戶(hù)端上傳的文件并進(jìn)行展示。
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) {
//每次上傳文件,這個(gè)回調(diào)至少執(zhí)行一次,執(zhí)行次數(shù)取決于上傳文件次數(shù)
if (part.isFile()) {
//創(chuàng)建文件,用于寫(xiě)入上傳的圖片
String s = System.currentTimeMillis() + part.getFilename();
File cache_file = new File(mFile.getAbsolutePath(), s);
try {
//因?yàn)榉椒ǘ啻螆?zhí)行,所以判斷不為空就關(guān)閉流
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) {
//每接收一次文件,這個(gè)回調(diào)至少執(zhí)行一次,執(zhí)行次數(shù)不固定,取決于上傳的單個(gè)文件的大小,所以不要以為這個(gè)方法執(zhí)行了,就代表文件已經(jīng)上傳結(jié)束了,是否結(jié)束取決于上面的onPart是否再次執(zhí)行
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 {
//文件上傳結(jié)束,在這里可以直接用glide就可以加載我們保存在本地的圖片了
if (mFileOutputStream != null) {
mFileOutputStream.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
});
運(yùn)行程序,用postman測(cè)試:

運(yùn)行效果如下:

既然用postman能上傳成功,那客戶(hù)端自己采用合適的網(wǎng)絡(luò)框架也可以成功上傳文件了。至此,使用androidasync在局域網(wǎng)操作文件的流程就結(jié)束了,在這里可以看到這個(gè)框架在局域網(wǎng)通信的便捷之處,androidasync也提供了一系列其他的局域網(wǎng)長(zhǎng)鏈接操作,有感興趣的朋友可以去嘗試一下,如果有寫(xiě)錯(cuò)的地方也請(qǐng)各位指教。謝謝