Android 设置网络代理

0x00 前言

做过Android开发的同学,一定都有和服务端联调接口的经历,昨天才刚刚把接口调通,服务端同学“一不小心”又把接口的返回字段格式改了,一连串的崩溃就来了,跟代码跟了半天,原来是服务端下发的有个字段格式不对。这种排错的方式,效率异常的低。如果我们能够一开始就去check服务端下发的数据是否正确,就可以更加快速的定位问题。所以,抓包在客户端开发中,显得尤为重要。

0x01 抓包工具

在笔者的应用中,主要是抓HTTP/HTTPS的包,当然也有时候会抓TCP包。

常用的抓包工具有如下几种:

  • Fiddler 可以抓HTTP/HTTPS的包(可以自己写插件处理网络请求与Response结果)
  • Charless 可以抓HTTP/HTTPS的包
  • WireShark 用来抓TCP的包,分析TCP报文灰常强大

上面,是笔者使用比较多的抓包工具。

PS:

  1. Charles是收费软件,有钱的同学们建议购买正版。
  2. HTTPS的抓包与HTTP类似,只需要给手机装上Charles的证书就行(代码里面没有对证书进行校验才可喔。)

0x02 代理手动配置

要能够抓到包,前提是你的手机与你的电脑要在同一个局域网上。然后将你手机的网络代理设置到你的电脑的ip上。

Fiddler 使用教程传送门

Charles 使用教程传送门

0x03 使用命令配置

使用命令修改Android手机系统的配置,如下代码:

// 设置代理
adb shell settings put global http_proxy ip_address:port

// 移除代理
adb shell settings delete global http_proxy
adb shell settings delete global global_http_proxy_host
adb shell settings delete global global_http_proxy_port

移除代理需要重启手机方可生效,设置可直接多次覆盖,不需要移除

使用adb来修改 settings中的值,修改的是系统的环境配置,你可以在项目中使用Java代码获取到修改的值:

// 打印所有的属性
Properties properties = System.getProperties();
for (Map.Entry<Object, Object> property : properties.entrySet()) {
    Log.d("TAG", property.getKey() + "=" + property.getValue());
}

// 仅读取代理host和post
System.getProperty("http.proxyHost"); // https.proxyHost
System.getProperty("http.proxyPort"); // https.proxyPort

那网络请求是怎么连接上代理设置的呢?

OKHTTP为例:

// OkHttpClient.Builder 
public Builder() {
	// 初始化
    proxySelector = ProxySelector.getDefault();
    if (proxySelector == null) {
        proxySelector = new NullProxySelector();
    }
    // 其它初始化操作省略
}

可以看到, 默认使用的是 ProxySelector.getDefault()

/**
 * Supports proxy settings using system properties This proxy selector
 * provides backward compatibility with the old http protocol handler
 * as far as how proxy is set
 *
 * Most of the implementation copied from the old http protocol handler
 *
 * Supports http/https/ftp.proxyHost, http/https/ftp.proxyPort,
 * proxyHost, proxyPort, and http/https/ftp.nonProxyHost, and socks.
 * NOTE: need to do gopher as well
 */
public abstract class ProxySelector {
    private static ProxySelector theProxySelector;
    static {
        try {
            Class<?> c = Class.forName("sun.net.spi.DefaultProxySelector");
            if (c != null && ProxySelector.class.isAssignableFrom(c)) {
                theProxySelector = (ProxySelector) c.newInstance();
            }
        } catch (Exception e) {
            theProxySelector = null;
        }
    }
    public static ProxySelector getDefault() {
        return theProxySelector;
    }
}

可以看到,这个地方默认使用的是 DefaultProxySelector

0x04 命令修改最佳实践

因为笔者公司的网络IP地址是动态的,每一次在手机系统里面的网络上修改代理,这是一个让人崩溃的事情,所以结合 0x03 中介绍的方式结合,自己写了一个脚本来获取ip地址,并重设代理:

#!/bin/bash
# 可以指定网卡,默认使用 en0
EN0=$1
if [ ! $EN0 ]; then
	EN0="en0"
fi
echo "current network card:$EN0"
# 获取当前网卡的ip地址
ipAddress=`ifconfig $EN0 | grep 'inet ' | grep -v 127.0.0.1 | cut -d\  -f2`
echo "current ip address: $ipAddress"
echo "setting android devices global http_proxy:$ipAddress:8888"
echo "  current shell:"
echo "  adb shell settings put global http_proxy $ipAddress:8888"
# 使用settings设置的命令来设置代理
adb shell settings put global http_proxy "$ipAddress:8888"%

0x05 使用Android App来修改(未完待续)

你可能感兴趣的:(Android的奇技淫巧)