一、场景:
想没想过在自己的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上。
|