在 Android 上使用 tio-boot 运行 HTTP 服务

本文档提供了在 Android 设备上通过tio-boot运行 HTTP 服务的详细步骤。tio-boot是一个轻量级的 HTTP 服务框架,可用于处理 HTTP 请求。

步骤 1: 添加依赖项

在你的build.gradle文件中添加以下依赖项,以引入必要的库。

// 在build.gradle中添加以下依赖项以支持tio-boot和相关功能
implementation 'com.litongjava:android-view-inject:1.0'
implementation 'com.litongjava:litongjava-android-utils:1.0.0'
implementation 'com.litongjava:tio-boot:1.5.2'

步骤 2: 创建 handler

创建一个 Controller 类(例如HelloController),该类包含处理 HTTP 请求的方法。

// 在com.litongjava.android.tio.boot.controller包下创建HelloController类
package com.litongjava.android.tio.boot.controller;

import com.litongjava.tio.http.common.HttpRequest;
import com.litongjava.tio.http.common.HttpResponse;
import com.litongjava.tio.http.server.util.Resps;

public class HelloController {

  public HttpResponse hello(HttpRequest httpRequest) {
    return Resps.txt(httpRequest, "hello");
  }

  public HttpResponse hi(HttpRequest httpRequest) {
    return Resps.txt(httpRequest, "hi");
  }
}

步骤 3: 启动服务

使用TioBootServerApp类来配置和启动 HTTP 服务。

package com.litongjava.android.tio.boot.controller;

import com.blankj.utilcode.util.NetworkUtils;
import com.litongjava.android.tio.boot.MainActivity;
import com.litongjava.jfinal.aop.Aop;
import com.litongjava.jfinal.aop.annotation.AImport;
import com.litongjava.tio.boot.TioApplication;
import com.litongjava.tio.boot.server.TioBootServer;
import com.litongjava.tio.http.server.handler.SimpleHttpRoutes;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

//不支持
//@AImport(IndexController.class)
public class TioBootServerApp {
  private static Logger log = LoggerFactory.getLogger(TioBootServerApp.class);

  public static void run() {
    long start = System.currentTimeMillis();
    // 创建simpleHttpRoutes
    SimpleHttpRoutes simpleHttpRoutes = new SimpleHttpRoutes();
    // 创建controller
    HelloController helloController = Aop.get(HelloController.class);

    // 添加action
    simpleHttpRoutes.add("/hi", helloController::hi);
    simpleHttpRoutes.add("/hello", helloController::hello);

    // 将simpleHttpRoutes添加到TioBootServer
    TioBootServer.setHttpRoutes(simpleHttpRoutes);

    String ipAddressByWifi = NetworkUtils.getIpAddressByWifi();
    log.info("ipAddressByWifi:{}", ipAddressByWifi);
    String[] args = new String[]{"--server.port=10051", "--tio.mvc.route.printMapping=true"};
    TioApplication.run(TioBootServerApp.class, args);
    long end = System.currentTimeMillis();
    System.out.println((end - start) + "(ms)");
  }
}

在这个类中,我们创建了一个SimpleHttpRoutes实例来定义路由,并将其添加到TioBootServer中。我们还通过 WiFi 获取 IP 地址,并启动了 TioApplication。

步骤 4: 配置 AndroidManifest.xml

在你的AndroidManifest.xml文件中添加必要的权限。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  package="com.litongjava.android.tio.boot">

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

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

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


  <application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/Theme.Litongjavatiobootforandroidstudy">
    <activity android:name=".MainActivity">
      <intent-filter>
        <action android:name="android.intent.action.MAIN" />

        <category android:name="android.intent.category.LAUNCHER" />
      </intent-filter>
    </activity>
  </application>

</manifest>

步骤 5: 设计 UI 界面

activity_main.xml中添加一个按钮,用户可以通过点击该按钮来启动 HTTP 服务。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:tools="http://schemas.android.com/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  tools:context=".MainActivity">

  <Button
    android:id="@+id/startBtn"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@color/purple_200"
    android:text="启动"></Button>

</LinearLayout>

步骤 6: MainActivity 获取权限并启动服务

MainActivity类中,请求必要的权限并在授权后启动服务。

package com.litongjava.android.tio.boot;

import androidx.appcompat.app.AppCompatActivity;

import android.Manifest;
import android.os.Bundle;
import android.view.View;

import com.blankj.utilcode.util.NetworkUtils;
import com.litongjava.android.tio.boot.controller.HelloController;
import com.litongjava.android.tio.boot.controller.IndexController;
import com.litongjava.android.tio.boot.controller.TioBootServerApp;
import com.litongjava.android.utils.acp.AcpUtils;
import com.litongjava.android.utils.toast.ToastUtils;
import com.litongjava.android.view.inject.annotation.FindViewByIdLayout;
import com.litongjava.android.view.inject.annotation.OnClick;
import com.litongjava.android.view.inject.utils.ViewInjectUtils;
import com.litongjava.jfinal.aop.Aop;
import com.litongjava.tio.boot.TioApplication;
import com.litongjava.tio.boot.http.routes.TioBootHttpRoutes;
import com.litongjava.tio.boot.server.TioBootServer;
import com.litongjava.tio.http.server.handler.HttpRoutes;
import com.litongjava.tio.http.server.handler.SimpleHttpRoutes;
import com.mylhyl.acp.AcpListener;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Arrays;
import java.util.List;

@FindViewByIdLayout(R.layout.activity_main)
public class MainActivity extends AppCompatActivity {
  private Logger log = LoggerFactory.getLogger(this.getClass());

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    //setContentView(R.layout.activity_main);
    ViewInjectUtils.injectActivity(this, this);
  }

  @OnClick(R.id.startBtn)
  public void startBtnOnClick(View view) {
    String[] permissions = {
      //写入外部设备权限
      Manifest.permission.ACCESS_NETWORK_STATE,
      Manifest.permission.ACCESS_WIFI_STATE,
      Manifest.permission.INTERNET,
      Manifest.permission.READ_EXTERNAL_STORAGE,
      Manifest.permission.WRITE_EXTERNAL_STORAGE

    };
    //创建acpListener
    AcpListener acpListener = new AcpListener() {
      @Override
      public void onGranted() {
        TioBootServerApp.run();
      }

      @Override
      public void onDenied(List<String> permissions) {
        ToastUtils.defaultToast(getApplicationContext(), permissions.toString() + "权限拒绝,无法写入日志");
      }
    };

    AcpUtils.requestPermissions(this, permissions, acpListener);

  }
}

在这个类中,我们使用AcpUtils来请求权限,并在权限被授予后启动TioBootServerApp。 启动日志

2024-01-28 22:58:28.280 [main] INFO  TioBootServerApp.run:34 - ipAddressByWifi:10.0.1.64
2024-01-28 22:58:28.347 [main] INFO  TioServer.start:167 -
|----------------------------------------------------------------------------------------|
| t-io site         | https://www.litongjava.com/t-io                                    |
| t-io on gitee     | https://gitee.com/ppnt/t-io                                        |
| t-io on github    | https://github.com/litongjava/t-io                                 |
| t-io version      | 3.7.3.v20240113-RELEASE                                            |
| ---------------------------------------------------------------------------------------|
| TioConfig name    | tio-boot                                                           |
| Started at        | 2024-01-28 22:58:28                                                |
| Listen on         | 0.0.0.0:10051                                                      |
| Main Class        | com.android.internal.os.ZygoteInit                                 |
| Jvm start time    | Not available in Android                                           |
| Tio start time    | 37ms                                                               |
| Pid               | Not available in Android                                           |
|----------------------------------------------------------------------------------------|
2024-01-28 22:58:28.351 [main] INFO  TioApplicationContext.run:128 - scan class and init:8(ms),server:58(ms),config:1(ms),http reoute:0(ms)
2024-01-28 22:58:28.353 [main] INFO  TioApplicationContext.printUrl:146 - port:10051
http://localhost:10051
108(ms)

测试访问

  • http://10.0.1.64:10051/hi
  • http://10.0.1.64:10051/hello

注意事项

  1. tio-bootcontroller不支持在 Android 系统中运行。
  2. tio-http-serverhandler支持在 Android 系统中运行。