Android使用NanoHttpd在app内搭建http server(一)

一、场景:

想没想过在自己的Android的 app里内嵌一个http server服务端,这样咱们就可以从PC和手机上的浏览器遥控app了。接下来就使用一个GitHub的开源库Nanohttpd在app内搭建一个小型http的server。开源库地址:GitHub - NanoHttpd/nanohttpd: Tiny, easily embeddable HTTP server in Java.

二、简单集成使用

引入依赖库:implementation 'org.nanohttpd:nanohttpd:2.3.1'

写一个类继承依赖库的NanoHTTPD.java,具体对外提供资源访问的代码在重写的serve方法中,

/**
 * Date: 2022/4/19
 * Author: SunBinKang
 * Description: 传入主机IP和自定义的端口号,这里的主机明要为安装app的那台设备的网络IP地址
 */
class HttpServerV1(hostname: String?, port: Int) : NanoHTTPD(hostname, port) {//继承NanoHTTPD

    private val TAG = "binkang"
    private var count = 0 //用于记录请求为第几次
    private var mGson: Gson = Gson() //用于记录请求为第几次


    override fun serve(session: IHTTPSession?): Response {
        return dealWith(session)
    }

    private fun dealWith(session: IHTTPSession?): Response {
        //日志输出外部请求相关的日志信息
        Log.i(
            TAG,
            "dealWith: session.uri = ${session?.uri}, method = ${session?.method}, header = ${session?.headers}, " +
                    "params = ${session?.parameters}"
        )
        //响应get请求
        if (Method.GET == session?.method) {

            if (session.uri == HTTP_URI_SAYSOMETHING) {
                count++
                val param = session.parameters
                return responseJsonString(
                    200,
                    "${param["name"]?.get(0)}, say somthing to me $count, ok?",
                    "请求成功!"
                )
            }

        } else if (Method.POST == session?.method) {//响应post请求
            //获取请求头数据
            val header = session.headers
            //获取传参参数
            val param = session.parameters

            return when (session.uri) {

                HTTP_URI_SUM -> {
                    var b: Int = param["number"]?.get(0).toString().toInt()
                    for (i in 0..100) {
                        b += 1
                    }
                    responseJsonString(200, b, "Success!")
                }

                HTTP_URI_HELLO -> responseJsonString(
                    200,
                    "Hello ${param["name"]?.get(0)} !",
                    "Success!"
                )

                else -> responseJsonString(404, "It's nothing!", "Success!")

            }
        }
        return responseJsonString(404, "", "Request not support!")
    }

    private fun <T : Any> responseJsonString(code: Int, data: T, msg: String): Response {
        val response = Responser<T>(code, data, msg)
        Log.i(TAG, "responseJsonString: $response")
        return newFixedLengthResponse(mGson.toJson(response))//返回对应的响应体Response
    }
}

再新建一个配置常量类:Config.kt

const val HTTP_IP = "10.153.205.27"//这是我当前手机流量下的IP地址
const val HTTP_PORT = 8080
const val HTTP_URL = "http://${HTTP_IP}:${HTTP_PORT}/"

/**
 * POST请求:
 * @param number (integer 数字)
 * {
 *   "code":200,
 *   "data":106,
 *   "msg":"请求成功!"
 * }
 */
const val HTTP_URI_SUM = "/api/sumHundredTime"

/**
 * POST请求:
 * @param name (String 数字)
 * {
 *   "code":200,
 *   "data":"Hello 叫啥来着 !",
 *   "msg":"请求成功!"
 * }
 */
const val HTTP_URI_HELLO = "/api/holleMan"

/**
 * GET请求:
 * @param name (String 数字)
 * {
 *   "code":200,
 *   "data":"哈哈哈哈, say somthing to me 1, ok?",
 *   "msg":"请求成功!"
 * }
 */
const val HTTP_URI_SAYSOMETHING = "/api/saySomething"

上面的IP是我手机流量下的IP地址:如果是连了WiFi的写上WiFi的IP地址也行,端口port自定义就行。

Responser.kt类

class Responser<T>(val code: Int, val data: T, val msg: String) {
}

然后就是在AndroidManifest.xml加上网络权限

<uses-permission android:name="android.permission.INTERNET" />

最后就是我们在mainActivity.java中启动这个server了:

class MainActivity : AppCompatActivity() {

    var mHttpServer: HttpServerV1? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        mHttpServer = HttpServerV1(HTTP_IP, HTTP_PORT)
        //三种启动方式都行
//        mHttpServer.start()
//        mHttpServer.start(NanoHTTPD.SOCKET_READ_TIMEOUT)
        mHttpServer?.start(NanoHTTPD.SOCKET_READ_TIMEOUT, false)
    }

    override fun onDestroy() {
        super.onDestroy()
        mHttpServer?.stop()//停止
    }
}

以上就完成了。说明一下我的build.gradle环境

plugins {
    id 'com.android.application'
    id 'kotlin-android'
}

android {
    compileSdkVersion 30
    buildToolsVersion "30.0.2"

    defaultConfig {
        applicationId "com.example.nanohttpd"
        minSdkVersion 19
        targetSdkVersion 30
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    kotlinOptions {
        jvmTarget = '1.8'
    }
}

dependencies {

    implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
    testImplementation 'junit:junit:4.+'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
    implementation 'org.nanohttpd:nanohttpd:2.3.1'
    implementation 'com.google.code.gson:gson:2.8.6'
}

运行试试,手机浏览器访问成功:

电脑postman访问get请求:

 

 这样在android中,一个简单的http server就搭建好了。

后续会上传项目到GitHub上。代码地址在下一篇的文章最后面~。

猜你喜欢

转载自blog.csdn.net/sunbinkang/article/details/124305235