构建简单Android HttpServer和HttpClient

完成Device之间的文件传输demo, 可以通过WiFi传输, 也可以用通用的HTTP协议, 因为只是演示作用, 因此 选择NanoHTTPD(https://github.com/NanoHttpd/nanohttpd),
NanoHTTPD免费/轻量级的(只有一个Java文件), 可以用来搭建http server,可以很好地嵌入到Java程序中,支持 GET, POST, PUT, HEAD 和 DELETE 请求,支持文件上传,占用内存很小. 我们可以根据自己的需求进行简单的封装,
github上有对这个库进行了简单封装(implementation 'cn.hotapk:fhttpserver:0.4.0'), 其实就是加入了注解反射, 使用更加简单
httpclient 使用了AsyncHttpClient(https://github.com/loopj/android-async-http), 使用起来也很简单,
官方文档:loopj.com/android-async-http
具体的例子解析:https://blog.csdn.net/maybeforever/article/details/88073914

HttpServer:
在子线程中启动服务:

implementation 'cn.hotapk:fhttpserver:0.4.0'
FHttpManager fHttpManager;
fHttpManager = FHttpManager.init(this, UserController.class);
fHttpManager.setPort(8000);
fHttpManager.setAllowCross(true);
fHttpManager.startServer();
public class UserController {
     private String defaultStatus;
     private IProcessListener mListener;
    //客户端上传文件, 服务器接收文件
    @RequestMapping("upload")
    public String upload(NanoHTTPD.IHTTPSession session) {
       ToastUtils.showShort("Received a message");
       boolean result = FFileUploadUtils.uploadFile(session, Constants.getBitmapPath(), "file")
if (uploadStatus) {

                    final CountDownLatch latch = new CountDownLatch(1);
                    mListener = new IProcessListener() {
                        @Override
                        public void success(String status) {
                            defaultStatus = status;
                            latch.countDown();
                        }

                        @Override
                        public void failure(String error) {
                            defaultStatus = error; 
                            latch.countDown();
                        }
                    };
                    parseFile(fileDir + "/" + parms.get(parm));
                    latch.await();
                    return defaultStatus;
                } else {
                    return "Failed to download file";
                }
    }

    @RequestMapping("gethtml")
    public String getHtml() {
        ToastUtils.showShort("testHtml");
        return "index2.html";
    }
}

结束时销毁服务

if (fHttpManager != null) {
     fHttpManager.stopServer();
}
fHttpManager = null;

获取当前device的ip

    public static String getIPAddress(Context context) {
        NetworkInfo info = ((ConnectivityManager) context
                .getSystemService(Context.CONNECTIVITY_SERVICE)).getActiveNetworkInfo();
        if (info != null && info.isConnected()) {
            if (info.getType() == ConnectivityManager.TYPE_MOBILE) {//当前使用2G/3G/4G网络
                try {
                    //Enumeration en=NetworkInterface.getNetworkInterfaces();
                    for (Enumeration en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements(); ) {
                        NetworkInterface intf = en.nextElement();
                        for (Enumeration enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements(); ) {
                            InetAddress inetAddress = enumIpAddr.nextElement();
                            if (!inetAddress.isLoopbackAddress() && inetAddress instanceof Inet4Address) {
                                return inetAddress.getHostAddress();
                            }
                        }
                    }
                } catch (SocketException e) {
                    e.printStackTrace();
                }

            } else if (info.getType() == ConnectivityManager.TYPE_WIFI) {//当前使用无线网络
                WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
                WifiInfo wifiInfo = wifiManager.getConnectionInfo();
                String ipAddress = intIP2StringIP(wifiInfo.getIpAddress());//得到IPV4地址
                return ipAddress;
            }
        } else {
            //当前无网络连接,请在设置中打开网络
        }
        return null;
    }

HttpClient:

implementation 'com.loopj.android:android-async-http:1.4.10'
                        String path = "文件路径";
                        if (!isOnline(context)){
                            ToastUtils.showShort("Network is Unavailable!");
                            return false;
                        }
                        String url = "123.123.0.10";//可以通过getIPAddress获取,填入client Device中
                   
                        RequestParams params = new RequestParams();
                        try {
                            params.put("file", new File(path));
                        } catch(FileNotFoundException e) {
                            ToastUtils.showShort("File not found!");
                            return false;
                        }
                        AsyncHttpClient client = new AsyncHttpClient();
                        client.setTimeout(2000);
                        StringBuilder urlUpload = new StringBuilder();
                        if (!url.contains("http")){
                            urlUpload.append("http://");
                        }
                        urlUpload.append(url);
                        urlUpload.append(":8000/upload");
                        ToastUtils.showShort("IP: "+urlUpload);
                        client.post(urlUpload.toString(), params, new AsyncHttpResponseHandler() {
                            @Override
                            public void onSuccess(int statusCode, cz.msebera.android.httpclient.Header[] headers, byte[] responseBody) {
                                Log.i("upload", "upload success");
                                ToastUtils.showShort("success");
                            }

                            @Override
                            public void onFailure(int statusCode, cz.msebera.android.httpclient.Header[] headers, byte[] responseBody, Throwable error) {
                                Log.i("upload", "upload failure");
                                ToastUtils.showShort("Failure:"+error.getMessage());
                            }
                        });
public static boolean isOnline(Context context) {
        ConnectivityManager cm = (ConnectivityManager) context.getSystemService(CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = null;
        try {
            networkInfo = cm.getActiveNetworkInfo();
        } catch (Exception e) {
            // #1405 shows that this throws a SecurityException.
            // b/70869360 shows that this throws NullPointerException on APIs 22, 23, and 24.
            // b/70869360 also shows that this throws RuntimeException on API 24 and 25.
            Log.e("isOnline", "exception: " + CommonTool.getExceptionMessage(e));
            // 无法判断, 就返回true
            return true;
        }

        if (networkInfo != null && networkInfo.isAvailable() && networkInfo.isConnected()) {
            return true;
        }
        return false;
    }

PS:
接收请求是异步进行的,中间会调用其它异步操作进行处理,如何进行接收异步调用结果并返回呢?

用CountDownLatch 啦,异步请求转阻塞式同步请求

CountDownLatch latch = new CountDownLatch(1);

异步回调 latch.countDown();

你可能感兴趣的:(构建简单Android HttpServer和HttpClient)