刚刚接触AndServer,感觉可以做很多事情,简单的梳理一下使用的逻辑,毕竟也是刚刚接触,对AndServer的理解还很浅显。感觉云控群控可以搞一搞,搭配上appium之类的。
1.项目中使用到的依赖
implementation 'com.google.code.gson:gson:2.8.0'
//这两个是AndServer中必须要用到的
implementation 'com.yanzhenjie.andserver:api:2.1.9'
annotationProcessor 'com.yanzhenjie.andserver:processor:2.1.9'
并且需要在项目model中的gradle添加
apply plugin: 'com.android.application'
//加上就行了
apply plugin: 'com.yanzhenjie.andserver'
然后是项目中的gradle
buildscript {
repositories {
...
google { url 'https://maven.aliyun.com/repository/google' }
jcenter { url 'https://maven.aliyun.com/repository/jcenter' }
mavenCentral { url 'https://maven.aliyun.com/repository/central' }
}
dependencies {
...
classpath 'com.yanzhenjie.andserver:plugin:2.1.9'
}
}
allprojects {
repositories {
...
google { url 'https://maven.aliyun.com/repository/google' }
jcenter { url 'https://maven.aliyun.com/repository/jcenter' }
mavenCentral { url 'https://maven.aliyun.com/repository/central' }
}
}
然后,编译时遇到个小麻烦,AndServer支持的gradle版本最小应该是5.6.4
自己在 gradle-wrapper.properties文件中修改一个就可以了。
2.两个我用到的工具类。
当然是从人家示例中直接拿来主义的,其中还有不少其他的东西,由于暂时用不到所以,就不贴了。
public class FileUtils {
/**
* SD is available.
*
* @return true, otherwise is false.
*/
public static boolean storageAvailable() {
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
File sd = new File(Environment.getExternalStorageDirectory().getAbsolutePath());
return sd.canWrite();
} else {
return false;
}
}
}
public class NetUtils {
/**
* Ipv4 address check.
*/
private static final Pattern IPV4_PATTERN = Pattern.compile(
"^(" + "([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}" +
"([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$");
/**
* Check if valid IPV4 address.
*
* @param input the address string to check for validity.
*
* @return True if the input parameter is a valid IPv4 address.
*/
public static boolean isIPv4Address(String input) {
return IPV4_PATTERN.matcher(input).matches();
}
/**
* Get local Ip address.
*/
public static InetAddress getLocalIPAddress() {
Enumeration<NetworkInterface> enumeration = null;
try {
enumeration = NetworkInterface.getNetworkInterfaces();
} catch (SocketException e) {
e.printStackTrace();
}
if (enumeration != null) {
while (enumeration.hasMoreElements()) {
NetworkInterface nif = enumeration.nextElement();
Enumeration<InetAddress> inetAddresses = nif.getInetAddresses();
if (inetAddresses != null) {
while (inetAddresses.hasMoreElements()) {
InetAddress inetAddress = inetAddresses.nextElement();
if (!inetAddress.isLoopbackAddress() && isIPv4Address(inetAddress.getHostAddress())) {
return inetAddress;
}
}
}
}
}
return null;
}
}
3.然后是Service用来启动AndServer的
public class CoreService extends Service {
private Server mServer;
@Override
public void onCreate() {
mServer = AndServer.webServer(this)
.port(8080)//端口号
.timeout(10, TimeUnit.SECONDS)//超时时间 单位
.listener(new Server.ServerListener() {//监听AndServer状态
@Override
public void onStarted() {
InetAddress address = NetUtils.getLocalIPAddress();
AndServerManage.onServerStart(CoreService.this, address.getHostAddress());
}
@Override
public void onStopped() {
AndServerManage.onServerStop(CoreService.this);
}
@Override
public void onException(Exception e) {
e.printStackTrace();
AndServerManage.onServerError(CoreService.this, e.getMessage());
}
})
.build();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
startServer();
return START_STICKY;
}
@Override
public void onDestroy() {
stopServer();
super.onDestroy();
}
private void startServer() {
mServer.startup();
}
private void stopServer() {
mServer.shutdown();
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
4.AndServer管理操作类
public class AndServerManage extends BroadcastReceiver {
private static final String ACTION = "com.wsy.myapplication.receiver";
private static final String CMD_KEY = "CMD_KEY";
private static final String MESSAGE_KEY = "MESSAGE_KEY";
private static final int CMD_VALUE_START = 1;
private static final int CMD_VALUE_ERROR = 2;
private static final int CMD_VALUE_STOP = 4;
/**
* Notify serverStart.
*
* @param context context.
*/
public static void onServerStart(Context context, String hostAddress) {
sendBroadcast(context, CMD_VALUE_START, hostAddress);
}
/**
* Notify serverStop.
*
* @param context context.
*/
public static void onServerError(Context context, String error) {
sendBroadcast(context, CMD_VALUE_ERROR, error);
}
/**
* Notify serverStop.
*
* @param context context.
*/
public static void onServerStop(Context context) {
sendBroadcast(context, CMD_VALUE_STOP);
}
private static void sendBroadcast(Context context, int cmd) {
sendBroadcast(context, cmd, null);
}
private static void sendBroadcast(Context context, int cmd, String message) {
Intent broadcast = new Intent(ACTION);
broadcast.putExtra(CMD_KEY, cmd);
broadcast.putExtra(MESSAGE_KEY, message);
context.sendBroadcast(broadcast);
}
private MainActivity mActivity;
private Intent mService;
public AndServerManage(MainActivity activity) {
this.mActivity = activity;
mService = new Intent(activity, CoreService.class);
}
/**
* Register broadcast.
*/
public void register() {
IntentFilter filter = new IntentFilter(ACTION);
mActivity.registerReceiver(this, filter);
}
/**
* UnRegister broadcast.
*/
public void unRegister() {
mActivity.unregisterReceiver(this);
}
public void startServer() {
mActivity.startService(mService);
}
public void stopServer() {
mActivity.stopService(mService);
}
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (ACTION.equals(action)) {
int cmd = intent.getIntExtra(CMD_KEY, 0);
switch (cmd) {
case CMD_VALUE_START: {
String ip = intent.getStringExtra(MESSAGE_KEY);
mActivity.onServerStart(ip);
break;
}
case CMD_VALUE_ERROR: {
String error = intent.getStringExtra(MESSAGE_KEY);
mActivity.onServerError(error);
break;
}
case CMD_VALUE_STOP: {
mActivity.onServerStop();
break;
}
}
}
}
}
5.MinaActivity
就是启动一下然后,改变一下布局的文字看看ip之类的没啥好说的
public class MainActivity extends AppCompatActivity {
AndServerManage andServerManage;
private TextView tv_ip;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv_ip = findViewById(R.id.tv_ip);
andServerManage = new AndServerManage(this);
andServerManage.register();
andServerManage.startServer();
}
@Override
protected void onDestroy() {
super.onDestroy();
andServerManage.unRegister();
}
public void onServerStart(String ip) {
tv_ip.setText("onServerStart http://" + ip + ":8080/");
}
public void onServerError(String message) {
tv_ip.setText("onServerError " + message);
}
public void onServerStop() {
tv_ip.setText("onServerStop");
}
}
6.controller 应该就叫接口了吧
就是注册接口,以及接到请求之后处理的类,具体我是不知道,我是问的好大哥。
@RestController
//@RequestMapping(path = "/wsy") 为请求路径 即完整路径为 ip:port/wsy/各个方法
@RequestMapping(path = "/wsy")
class TestController {
@RequestMapping(
path = "/connection",
method = {RequestMethod.GET},
produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
Object getConnection(HttpRequest request) {
Map<String, Object> map = new HashMap<>();
map.put("getLocalAddr", request.getLocalAddr());
map.put("getLocalName", request.getLocalName());
map.put("getLocalPort", request.getLocalPort());
map.put("getRemoteAddr", request.getRemoteAddr());
map.put("getRemoteHost", request.getRemoteHost());
map.put("getRemotePort", request.getRemotePort());
Log.e("wsy", new Gson().toJson(map));
return map;
}
@CrossOrigin(methods = {RequestMethod.POST, RequestMethod.GET})
//上面的 是人家的 好大哥说有点作用我就没删 但是删掉应该没有大病
//这下面是我研究写的 简单的接口 接俩个参数 加法 之后返回
//get接口 path = “/gettest”为请求路径
//@RequestParam("num1")int num1 为声明接收参数
@GetMapping(path = "/gettest", consumes = {"application/json", "!application/xml"})
String gettest(@RequestParam("num1")int num1,@RequestParam("num2")int num2) {
return "successful " + (num1 + num2);
}
//post接口
@PostMapping(path = "/posttest", consumes = {"application/json", "!application/xml"})
String posttest(@RequestParam("num1")int num1,@RequestParam("num2")int num2) {
return "successful " + (num1 + num2);
}
}
7.然后就是测试
运行真机 知道自己的 ip地址
然后用postman测试一手,看看效果
效果出来了,完事,这就满足我目前的需求了,剩下的之后在研究。