精华内容
下载资源
问答
  • Firefox for Android 代理设置
    千次阅读
    2020-11-22 15:12:49

    目前发现 Android 平台的浏览器原生支持代理配置的仅 Firefox for Android(官方下载),不仅支持 HTTP、HTTPS 和 Socks4、5,还支持 PAC 脚本。在 Firefox 中访问 about:config,使用 proxy 过滤器并的找到 network.proxy.socks, network.proxy.socks_port, network.proxy.socks_remote_dns, network.proxy.type 并更改成图中配置。
    HTTP代理配置:
    修改以下设置:
    network.proxy.http修改为127.0.0.1(默认值为空)
    network.proxy.http_port修改为8087(默认值为0)
    network.proxy.socks_remote_dns修改为true(默认值为false,须改为true)
    network.proxy.ssl修改为127.0.0.1
    network.proxy.ssl_port修改为8087
    network.proxy.type修改为1(默认值为5,必须改为1才能使用代理)

    更多相关内容
  • android代理设置代码

    2016-08-19 11:29:23
    android 代理设置 兼容低版本和高版本 基本兼容所有版本 并根据需要可以设置账号密码身份认证或者只用ip+port方式也行 亲测可行
  • 真正好用的android代理服务设置软件(无需root)
  • Android代理模式基础

    千次阅读 2021-05-16 15:18:01
    静态代理代理类持有被代理者的引用,在方法调用时,代理对象调用了被代理对象去执行真正的实现。 2.1 简单示例 假如对于一个日志处理功能,可通过代理代理实例日志处理类: // 1.首先定义接口层 interface ...

    一、代理模式

    代理模式的定义:为其他对象提供一种代理以控制对这个对象的访问。

    二、静态代理

    静态代理的代理类持有被代理者的引用,在方法调用时,代理对象调用了被代理对象去执行真正的实现。

    2.1 简单示例

    假如对于一个日志处理功能,可通过代理类代理实例日志处理类:

    // 1.首先定义接口层
    interface ILogProcessor {
        public void printLog(String log);
    }
    
    // 2.定义实现类
    public class MainLogProcessor implements ILogProcessor {
    
        @Override
        public void printLog(String log) {
            Log.d("LogProcessor", "MainLogProcessor" + log);
        }
    }
    
    // 3.定义代理类
    public class LogProcessorProxy implements ILogProcessor {
        // 代理类持有被代理类的引用
        private ILogPrinter mainLogProcessor = new MainLogProcessor();
    
        @Override
        public void printLog(String log) {
        	// 代理类需要完成的一些额外处理
            Log.d("LogProcessor", "ProxyLogProcessor" + log);
            String finalLog = Thread.currentThread() + log;
            mainLogPrinter.printLog(finalLog);
        }
    }
    

    这样,在使用过程中,可以按如下方式使用:

    public void main() {
    	String log = "important log";
    	ILogPrinter proxy = new LogPrinterProxy();
    	proxy.printLog(log);
    }
    

    2.2 AIDL

    AIDL中也用到了代理模式,在Android Studio中新建一个AIDL文件,如下所示:

    // IMyAidlInterface.aidl
    package com.bc.sample;
    
    interface IMyAidlInterface {
        void testFun();
    }
    

    在点击make project后,会自动生成AIDL接口对应的代码,即对应的Stub和Proxy,可以看到AIDL的Proxy是通过静态代理实现,自动生成的代码如下所示:

    package com.bc.sample;
    // Declare any non-default types here with import statements
    
    public interface IMyAidlInterface extends android.os.IInterface
    {
      /** Default implementation for IMyAidlInterface. */
      public static class Default implements com.bc.sample.IMyAidlInterface
      {
        @Override public void testFun() throws android.os.RemoteException
        {
        }
        @Override
        public android.os.IBinder asBinder() {
          return null;
        }
      }
      /** Local-side IPC implementation stub class. */
      public static abstract class Stub extends android.os.Binder implements com.bc.sample.IMyAidlInterface
      {
        private static final java.lang.String DESCRIPTOR = "com.bc.sample.IMyAidlInterface";
        /** Construct the stub at attach it to the interface. */
        public Stub()
        {
          this.attachInterface(this, DESCRIPTOR);
        }
        /**
         * Cast an IBinder object into an com.bc.sample.IMyAidlInterface interface,
         * generating a proxy if needed.
         */
        public static com.bc.sample.IMyAidlInterface asInterface(android.os.IBinder obj)
        {
          if ((obj==null)) {
            return null;
          }
          android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
          if (((iin!=null)&&(iin instanceof com.bc.sample.IMyAidlInterface))) {
            return ((com.bc.sample.IMyAidlInterface)iin);
          }
          return new com.bc.sample.IMyAidlInterface.Stub.Proxy(obj);
        }
        @Override public android.os.IBinder asBinder()
        {
          return this;
        }
        @Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
        {
          java.lang.String descriptor = DESCRIPTOR;
          switch (code)
          {
            case INTERFACE_TRANSACTION:
            {
              reply.writeString(descriptor);
              return true;
            }
            case TRANSACTION_testFun:
            {
              data.enforceInterface(descriptor);
              this.testFun();
              reply.writeNoException();
              return true;
            }
            default:
            {
              return super.onTransact(code, data, reply, flags);
            }
          }
        }
    
    	// 主要关注代理模式的实现;可以看到AIDL的Proxy是通过静态代理模式实现
        private static class Proxy implements com.bc.sample.IMyAidlInterface
        {
          private android.os.IBinder mRemote;
          Proxy(android.os.IBinder remote)
          {
            mRemote = remote;
          }
          @Override public android.os.IBinder asBinder()
          {
            return mRemote;
          }
          public java.lang.String getInterfaceDescriptor()
          {
            return DESCRIPTOR;
          }
          @Override public void testFun() throws android.os.RemoteException
          {
            android.os.Parcel _data = android.os.Parcel.obtain();
            android.os.Parcel _reply = android.os.Parcel.obtain();
            try {
              _data.writeInterfaceToken(DESCRIPTOR);
              boolean _status = mRemote.transact(Stub.TRANSACTION_testFun, _data, _reply, 0);
              if (!_status && getDefaultImpl() != null) {
                getDefaultImpl().testFun();
                return;
              }
              _reply.readException();
            }
            finally {
              _reply.recycle();
              _data.recycle();
            }
          }
          public static com.bc.sample.IMyAidlInterface sDefaultImpl;
        }
        static final int TRANSACTION_testFun = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
        public static boolean setDefaultImpl(com.bc.sample.IMyAidlInterface impl) {
          // Only one user of this interface can use this function
          // at a time. This is a heuristic to detect if two different
          // users in the same process use this function.
          if (Stub.Proxy.sDefaultImpl != null) {
            throw new IllegalStateException("setDefaultImpl() called twice");
          }
          if (impl != null) {
            Stub.Proxy.sDefaultImpl = impl;
            return true;
          }
          return false;
        }
        public static com.bc.sample.IMyAidlInterface getDefaultImpl() {
          return Stub.Proxy.sDefaultImpl;
        }
      }
      public void testFun() throws android.os.RemoteException;
    }
    

    三、动态代理

    在2.1的静态代理代码中,如果现在需要扩展一个新的接口,那就需要分别在接口层、实际处理类、代理类中分别改动,如下所示:

    // 1.首先定义接口层
    interface ILogSender {
    	public void sendLog(String log);
    }
    
    // 2.定义实现类
    public class MainLogSender implements ILogSender {
    
        @Override
        public void sendLog(String log) {
            Log.d("LogSender", "MainLogSender send" + log);
        }
    }
    
    // 3.定义代理类
    public class LogSenderProxy implements ILogSender {
        // 代理类持有被代理类的引用
        private ILogSender mainLogSender = new MainLogSender();
    
        @Override
        public void sendLog(String log) {
            // 代理类需要完成的一些额外处理
            Log.d("LogSender", "ProxyLogSender" + log);
            String finalLog = Thread.currentThread() + log;
            mainLogSender.sendLog(finalLog);
        }
    }
    

    当代理一个新的接口时可见,新的代理类与其他代理类代码是高度相似的,因此可以采用动态代理的方式来完成类似的功能。

    3.1 基础用法

    与静态代理不同,动态代理类的class是在运行过程中动态生成的。

    3.1.1 基础用法

    首先定义接口层:

    // 定义接口层
    interface ILogProcessor {
        public void printLog(String log);
    }
    

    然后使用Proxy.newProxyInstance完成动态代理如下:

    private void main() {
            ILogProcessor proxy = (ILogProcessor) Proxy.newProxyInstance(this.getClassLoader(), new Class<?>[] {ILogPrinter.class}, new InvocationHandler() {
    
                /**
                 * @param proxy 代理对象
                 * @param method 被调用的方法
                 * @param args 被调用的方法的参数列表
                 */
                @Override
                public Object invoke(Object proxy, Method method, Object[] args) {
                	String log = (String)args[0];
                	Log.d("LogProcessor", "ProxyLogProcessor" + log);
            String finalLog = Thread.currentThread() + log;
                     Log.d("LogProcessor", "printLog" + finalLog);
                    return null;
                }
            });
            
            proxy.printLog("");
        }
    

    其中,InvocationHandler就是将静态代理中需要实现的部分抽离了出来,即动态生成的Proxy代理了InvocationHandler。

    3.1.2 动态生成的class

    动态生成的代理类的方法实际调用都到了InvocationHandler的invoke方法,动态生成的代理类class伪代码如下:

    public final class $Proxy0 extends Proxy implements ILogProcessor {
    	static {
            m3 = Class.forName("com.bc.sample.ILogProcessor").getMethod("printLog");
       }
       private static Method m3;
       public void printLog(String log) {
       		// 实际调用到了InvocationHandler的invoke方法
       		super.h.invoke(this, m3, (Object[])log);
       }
    }
    

    3.1.3 源码分析

    下面分析Proxy.newProxyInstance的源码:

    public class Proxy implements java.io.Serializable {
    
    	// 动态生成的class的缓存;ProxyClassFactory可动态生成代理class
    	private static final WeakCache<ClassLoader, Class<?>[], Class<?>>
            proxyClassCache = new WeakCache<>(new KeyFactory(), new ProxyClassFactory());
        
        // 生成代理class并返回对应的实例
    	public static Object newProxyInstance(ClassLoader loader,
                                              Class<?>[] interfaces,
                                              InvocationHandler h)
        {
            Objects.requireNonNull(h);
            final Class<?>[] intfs = interfaces.clone();
            // 查找或动态生成代理类的class
            Class<?> cl = getProxyClass0(loader, intfs);
            // 获取动态代理类的构造函数
            final Constructor<?> cons = cl.getConstructor(constructorParams);
            final InvocationHandler ih = h;
            if (!Modifier.isPublic(cl.getModifiers())) {
            	cons.setAccessible(true);
            }
            // 通过反射调用构造函数返回代理类的实例;参数中的InvocationHandler对象作为参数传递给类构造函数;
            return cons.newInstance(new Object[]{h});
        }
    
    
    	// 获取动态代理类class
    	private static Class<?> getProxyClass0(ClassLoader loader,
                                               Class<?>... interfaces) {
            return proxyClassCache.get(loader, interfaces);
        }
    
    
    	private static final class ProxyClassFactory
            implements BiFunction<ClassLoader, Class<?>[], Class<?
        {
            // prefix for all proxy class names
            private static final String proxyClassNamePrefix = "$Proxy";
    
    		// WeakCache.get()会调用到apply,最终调用generateProxy生成动态代理类class
            @Override
            public Class<?> apply(ClassLoader loader, Class<?>[] interfaces) {
            	// ....
            	return generateProxy(proxyName, interfaces, loader, methodsArray,
                                         exceptionsArray);
            }
        }
    
    	// 动态生成代理类class
    	private static native Class<?> generateProxy(String name, Class<?>[] interfaces,
                                                     ClassLoader loader, Method[] methods,
                                                     Class<?>[][] exceptions);
    }
    

    3.2 Retrofit动态代理

    Retrofit是一个开源网络库,其源码中也使用到了动态代理模式。简单介绍如下:

    3.2.1 基础用法

    首先,新建网络请求对应的接口:

    public interface SampleRequestInterface {
    
        @HTTP(method = "GET", path = "/api", hasBody = true)
        Call<BaseResponse> getCall();
    }
    

    然后,使用Retrofit动态代理生成请求:

    public class MainActivity {
    
    	private void sendRequest() {
            try {
                Retrofit retrofit = new Retrofit.Builder()
                        .baseUrl("http://graph.baidu.com")
                        .addConverterFactory(GsonConverterFactory.create())
                        .build();
    
    			// 返回请求接口的代理类实例,内部实现是用动态代理实现
                SampleRequestInterface sampleRequest = retrofit.create(SampleRequestInterface.class);
                Call<BaseResponse> call = sampleRequest.getCall();
                // 异步发送请求
                call.enqueue(new Callback<BaseResponse>() {
                    @Override
                    public void onResponse(Call call, Response response) {
                        response.body();
                    }
    
                    @Override
                    public void onFailure(Call call, Throwable t) {
    
                    }
                });
                // 同步发送请求
                Response<BaseResponse> response = call.execute();
                response.body();
            } catch (Exception exception) {
                exception.printStackTrace();
            }
        }
    }
    

    3.2.2 Retrofit动态代理实现

    接下来分析Retrofit内部是如何使用动态代理模式的:

    public final class Retrofit {
    	
    	public <T> T create(final Class<T> service) {
        Utils.validateServiceInterface(service);
        if (validateEagerly) {
          eagerlyValidateMethods(service);
        }
        return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
            new InvocationHandler() {
              private final Platform platform = Platform.get();
    
              @Override public Object invoke(Object proxy, Method method, Object... args)
                  throws Throwable {
                // ...
                // 真正需要执行的代码
                ServiceMethod serviceMethod = loadServiceMethod(method);
                OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
                return serviceMethod.callAdapter.adapt(okHttpCall);
              }
            });
      }
    }
    

    The End

    欢迎关注我,一起解锁更多技能:BC的掘金主页~💐 BC的CSDN主页~💐💐
    个人信息汇总.png

    展开全文
  • Java中的动态代理给我们提供一种动态生成类的方式,有很好的灵活性,这种技术一般会出现在一些第三方框架中,来降低接入方的使用成本。
  • 安卓代理工具

    2015-01-05 18:08:27
    安卓代理工具,支持非root,连接速度还不错
  • 从shell设置Android代理

    2021-07-08 21:10:54
    title: 从shell设置Android代理 date: 2021-07-02 21:12:39 keywords: Android,shell设置代理 tags: Linux Android shell Proxy 因为蓝某模拟器并不能从设置里面设置代理,需要抓包调试的时候就很闹心 设置代理...

    title: 从shell设置Android代理
    date: 2021-07-02 21:12:39
    keywords: Android,shell设置代理
    tags:

    • Linux
    • Android
    • shell
    • Proxy

    因为蓝某模拟器并不能从设置里面设置代理,需要抓包调试的时候就很闹心

    设置代理:

    adb shell settings put global http_proxy ip:port
    

    如:

    adb shell settings put global http_proxy 172.16.21.14:8888
    

    移除代理(需三条指令全部执行,部分机型可能需要重启手机才能完全移除代理):

    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 reboot
    

    其他说明

    本人文章截至2021年5月22日仅在本人博客博客园简书平台发布,其他平台均为未授权发布。

    展开全文
  • Android代理模式简单Demo,项目里面simple包下为原理,UML类图通用模式代码,demo包下为具体案例:律师lawyer代理user打官司,DynamicProxy为动态加载代理模式类.各自调用均在对应包的client;同步博文:...
  • Android手机设置代理工具,需要root权限,可以通过工具设置手机连接wifi的代理
  • Android 中的代理模式3.1 Retrofit中的代理模式(没有被代理者) 1. 前言 首先看下百度百科对代理模式的介绍: 代理模式的定义:为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者...

    1. 前言

    首先看下百度百科对代理模式的介绍:

    代理模式的定义:为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。

    其实也就是中介模式或者委托模式。在日常生活中代理模式很多,比如叫同事带饭、打官司等。使用代理模式的主要意图为:为其他对象提供一种代理以控制对这个对象的访问。主要的使用场景为:当无法或不想直接访问某个对象时,可以通过一个代理对象来间接访问,为了保证客户端使用的透明性,委托对象与代理对象需要实现相同的接口

    Spring-AOP简介一文中曾提到过两种代理方式,即:静态代理和动态代理。

    • 静态代理:是由程序员创建或工具生成代理类的源码,再编译代理类。所谓静态也就是在程序运行前就已经存在代理类的字节码文件,代理类和委托类的关系在运行前就确定了。
    • 动态代理:是在实现阶段不用关心代理类,而在运行阶段才指定哪一个对象。

    这里继续围绕这两种方式进行回顾和展开。

    2. 代理模式(Proxy Pattern)

    2.1 静态代理模式

    比如下面的案例:

    interface ISubject {
        void doSomething();
    }
    
    // 真正的实现类
    class RealSubject_ZhangSan implements ISubject{
        @Override
        public void doSomething() {
            System.out.println("买手机");
        }
    }
    
    class ProxySubject_Shop implements ISubject{
    
        private RealSubject_ZhangSan mSubject;  // 真正做这件事的对象
    
        public ProxySubject_Shop(RealSubject_ZhangSan subject){
            this.mSubject = subject;
        }
    
        @Override
        public void doSomething() {  // 只做代理
            mSubject.doSomething();
        }
    }
    
    
    public class Client {
        public static void main(String[] args) {
            RealSubject_ZhangSan subject = new RealSubject_ZhangSan();
            // 构造代理对象
            ProxySubject_Shop proxySubject = new ProxySubject_Shop(subject);
            // 调用代理的方法
            proxySubject.doSomething();
        }
    }
    

    对应的类图为:
    在这里插入图片描述

    Client通过接口知道需要调用什么方法,而因为在代理模式中不能直接访问真正的目标对象,而需要通过代理对象来进行访问。所以在Client中需要使用代理对象,由于代理模式规定了需要保证客户端使用的透明性,所以被代理对象和代理对象都需要事项相同的接口,即这里的doSomething方法。

    值得注意的是,按照上面的写法对于每个具体的代理类,我们都需要在其中指定维护(代理)的具体Subject类,那么当有很多具体的RealSubject的时候,就需要定义很多的代理类,当然这是不合理的。所以在代理类中只有的应该是接口,比如:

    class ProxySubject_Shop implements ISubject{
    
        private ISubject mSubject;  // 真正做这件事的对象,面向接口编程而不要面向具体的实现
    
        public ProxySubject_Shop(ISubject subject){
            this.mSubject = subject;
        }
    
        @Override
        public void doSomething() {  // 只做代理
            mSubject.doSomething();
        }
    }
    

    虽然上面这种方式确实解决了存在多个真实主题类的情况,但是如果代理类需要在原有的真实Subject前或者后做一些自己独有的操作的时候,就需要根据代理类的种类,来定义多个代理类。这显然也是不合理的。所以就需要动态代理。

    从前面我们知道使用静态代理其实也就是在源码中直接指定。而动态代理方式相反,是通过反射的机制来动态地生成代理者的对象,也就是说代理谁将会在执行阶段决定。

    2.2 动态代理模式

    动态代理中所使用的技术也就是反射,在Java中提供了一个便捷的动态代理接口InvocationHandler以及相关的代理类Proxy

    • InvocationHandler:调用处理程序,并返回一个结果的;
    • Proxy:提供了创建动态代理类和实例的静态方法,用于生成动态代理的这个实例;
    interface ISubject {
        void doSomething();
    }
    
    // 真正的实现类
    class RealSubject_ZhangSan implements ISubject{
        @Override
        public void doSomething() {
            System.out.println("买手机");
        }
    }
    
    public class Client {
        public static void main(String[] args) {
            RealSubject_ZhangSan realSubject = new RealSubject_ZhangSan();
    
            // 动态构造一个代理者 ==> 代理realSubject
            ISubject subject = (ISubject) Proxy.newProxyInstance(realSubject.getClass().getClassLoader(),
                    new Class[]{ISubject.class}, new InvocationHandler() {
                        @Override
                        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                            return method.invoke(realSubject, args);
                        }
                    });
            // 得到类RealSubject_ZhangSan的实现接口Class对象
            // new Class[]{ISubject.class} 或者:RealSubject_ZhangSan.class.getInterfaces()  
    
            // 调用代理的方法
            subject.doSomething();
        }
    }
    

    当然这里可以抽离出来一个动态代理类:

    class DynamicProxy<T extends ISubject> implements InvocationHandler {
    
        private T mObj;
    
        public DynamicProxy(T obj){
            this.mObj = obj;
        }
    
        public ISubject getProxy(){
             return (ISubject) Proxy.newProxyInstance(mObj.getClass().getClassLoader(),
                     mObj.getClass().getInterfaces(), this);
        }
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            return method.invoke(mObj, args);
        }
    }
    
    
    public class Client {
        public static void main(String[] args) {
            RealSubject_ZhangSan realSubject = new RealSubject_ZhangSan();
            // 动态代理
            ISubject subject = new DynamicProxy<RealSubject_ZhangSan>(realSubject).getProxy();
            // 调用代理的方法
            subject.doSomething();
        }
    }
    
    

    对应的类图:
    在这里插入图片描述

    观察上面类图,可以直观的看到就是动态代理类和具体的实现类就没有直接关联关系了。而需要做的是在Client代理类中进行动态确定。可以看到就是这种方式的代码耦合度更低。也就是完成了代理者和被代理者之间的解耦,使得这两者之间没有直接的耦合关系。当然,静态代理类的方式更加符合面向对象原则,开发时具体使用哪种代理方式,就没有什么规定了。

    3. Android 中的代理模式

    Android中有ActivityManagerProxyActivityManagerService以及Retrofit等均有代理模式的身影。这里以Retrofit中的代理模式为例。

    3.1 Retrofit中的代理模式(没有被代理者)

    为了了解Retrofit中的代理模式,首先需要先引入相关依赖到项目中:

    // https://mvnrepository.com/artifact/com.squareup.retrofit2/retrofit
    implementation 'com.squareup.retrofit2:retrofit:2.9.0'
    

    对于怎么使用在Retrofit的使用案例中曾简单的使用过这个框架。这里做一个简单的回顾:

    • 定义指定具体的URL地址,来构造Retrofit对象;
    • 使用第一步得到的Retrofit实例对象调用create方法,当然这个方法中传入一个自定义的接口。在这个接口中完成链接返回数据转换为Java实例对象。
    • 类似的将请求加入到请求队列中,然后接收返回结果即可。

    而在Retrofit类中的create方法中就可以看见动态代理模式:

    public <T> T create(final Class<T> service) {
        validateServiceInterface(service);
        return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[]{service},
                new InvocationHandler() {
                    private final Platform platform = Platform.get();
                    private final Object[] emptyArgs = new Object[0];
    
                    @Override
                    public @Nullable
                    Object invoke(Object proxy, Method method,
                                  @Nullable Object[] args) throws Throwable {
                        // If the method is a method from Object then defer to normal invocation.
                        if (method.getDeclaringClass() == Object.class) {
                            return method.invoke(this, args);
                        }
                        if (platform.isDefaultMethod(method)) {
                            return platform.invokeDefaultMethod(method, service, proxy, args);
                        }
                        return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
                    }
                });
    }
    

    比如此时的请求接口还是像Retrofit的使用案例文中定义的一样,即:

    public interface RequestInterface {
    
        @GET(value = "/test/1.0/users")
        Call<List<User>> listUsers();   // retrofit2.Call;
    
        @GET(value = "/test/1.0/users/{userid}")
        Call<User> getUserById(@Path(value = "userid") char userId);
    
        @FormUrlEncoded
        @POST(value = "/test/1.0/users")
        Call<Void> addUser(@Field(value = "name") String name);
    }
    

    那么在构造Retrofit中的请求对象的时候,就在create方法中传入这个接口的Class对象:

    RequestInterface request = retrofit.create(RequestInterface.class);
    

    继续回到Retrofit类的create方法,可以发现生成的代理对象其实就是代理这个RequestInterface接口。但是值得注意的是,RequestInterface接口只是代理模式中的Subject,而我们这里需要找到真正的被代理对象类。但是很遗憾确实这里没有找到,那么不妨来仿写一下:

    interface ISubject {
        void doSomething();
    }
    
    public class Client {
        public static void main(String[] args) {
            ISubject subject = (ISubject) Proxy.newProxyInstance(ISubject.class.getClassLoader(),
                    new Class[]{ISubject.class}, new InvocationHandler() {
                        @Override
                        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                            System.out.println("invoke");
                            return 0;
                        }
                    });
    
            System.out.println("package: \n\t" + subject.getClass().getName());
            System.out.println("implemented interface: ");
            Class<?>[] interfaces = subject.getClass().getInterfaces();
            for (Class<?> anInterface : interfaces) {
                System.out.println("\t"+anInterface.getName());
            }
            System.out.println("fields: ");
            Field[] declaredFields = subject.getClass().getDeclaredFields();
            for (Field declaredField : declaredFields) {
                System.out.println("\t"+declaredField.getName());
            }
            System.out.println("methods: ");
            Method[] declaredMethods = subject.getClass().getDeclaredMethods();
            for (Method declaredMethod : declaredMethods) {
                System.out.println("\t"+declaredMethod.getName());
            }
    
            subject.doSomething();
        }
    }
    

    输出结果为:
    在这里插入图片描述
    Retrofit2 源码解析之动态代理一文中给出了得到生成的动态代理类的字节码数组并存储为.class文件的方式,即:

    private static void storageClassFile(ISubject subject){
        // subject 为上面生成的动态代理对象
        String proxyName = subject.getClass().getName() + ".class";
        byte[] clazz = ProxyGenerator.generateProxyClass(proxyName, new Class[]{ISubject.class});
        try {
            OutputStream out = new FileOutputStream(proxyName);
            InputStream is = new ByteArrayInputStream(clazz);
            byte[] buff = new byte[1024];
            int len;
            while ((len = is.read(buff)) != -1) {
                out.write(buff, 0, len);
            }
            is.close();
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    

    那么在这个项目的跟目录中可以看到生成的文件:

    在这里插入图片描述
    直接使用IDEA来进行打开:

    public final class class extends Proxy implements ISubject {
        private static Method m1;
        private static Method m3;
        private static Method m2;
        private static Method m0;
    
        public class(InvocationHandler var1) throws  {
            super(var1);
        }
    
        public final boolean equals(Object var1) throws  {
            try {
                return (Boolean)super.h.invoke(this, m1, new Object[]{var1});
            } catch (RuntimeException | Error var3) {
                throw var3;
            } catch (Throwable var4) {
                throw new UndeclaredThrowableException(var4);
            }
        }
    
        public final void doSomething() throws  {
            try {
                super.h.invoke(this, m3, (Object[])null);
            } catch (RuntimeException | Error var2) {
                throw var2;
            } catch (Throwable var3) {
                throw new UndeclaredThrowableException(var3);
            }
        }
    
        public final String toString() throws  {
            try {
                return (String)super.h.invoke(this, m2, (Object[])null);
            } catch (RuntimeException | Error var2) {
                throw var2;
            } catch (Throwable var3) {
                throw new UndeclaredThrowableException(var3);
            }
        }
    
        public final int hashCode() throws  {
            try {
                return (Integer)super.h.invoke(this, m0, (Object[])null);
            } catch (RuntimeException | Error var2) {
                throw var2;
            } catch (Throwable var3) {
                throw new UndeclaredThrowableException(var3);
            }
        }
    
        static {
            try {
                m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
                m3 = Class.forName("com.example.scan.kaoshi.ISubject").getMethod("doSomething");
                m2 = Class.forName("java.lang.Object").getMethod("toString");
                m0 = Class.forName("java.lang.Object").getMethod("hashCode");
            } catch (NoSuchMethodException var2) {
                throw new NoSuchMethodError(var2.getMessage());
            } catch (ClassNotFoundException var3) {
                throw new NoClassDefFoundError(var3.getMessage());
            }
        }
    }
    

    可以看到这个类确实是实现类ISubject接口的类,且实现了基本的hashCodetoStringequals方法。但是因为在ProxyGenerator.generateProxyClass方法存在于sun.misc.ProxyGenerator包中,而Android中并不支持这个包所以有必要继续看Retrofit中的源码:

    在这里插入图片描述
    可以看到其实首先通过loadServiceMethod(method)这个方法将调用的实际方法传递进去,然后在loadServiceMethod方法中进行Map<Method, ServiceMethod<?>>查找看是否已经存在这个方法,存在就直接返回,否则就通过ServiceMethod.parseAnnotations(this, method)方法来对声明接口中的这个方法的注解进行解析,在这个方法中会继续解析注解,最终会使用HttpServiceMethod.parseAnnotations方法来进行解析,由于代码比较多这里就不贴出来了。在这个方法中,首先得到这个方法的返回类型,然后使用Okhttp3来进行请求的封装,并且得到这个方法的所有注解,并进行对应的解析。最终会返回一个HttpServiceMethod对象到Retrofit.javacreate方法。我们之后后续的使用和Okhttp类似,也就是构建Call对象以及请求加入到队列中。

    所以在Retrofit中不完全是代理模式,很容易理解,因为在这个过程中确实没有RealSubject对象,而只存在接口和动态代理Proxy的对象。也比较好理解,因为在网络请求过程中,我们定义RESTful风格来进行请求链接和返回参数的定义,中间其实不需要一个真实的被代理类来实现这个请求,而是需要将其注解进行解析,得到实际有意义的请求参数和返回值类型,最终可以动态添加到Okhttp请求和满足动态封装Bean即可。

    在这个过程中由程序自己来处理注解,以及完成请求API的解析工作,进而可以在底层使用Okhttp进行网络请求的时候可以对参数以及返回值进行相关的数据封装。所以说其实在Retrofit中不完全是代理模式,因为没有(也不需要)实际上的被代理者。

    4. 后记

    在《Android源码设计模式》一书中提到:不少设计模式中都存在代理模式的影子,且在日常生活中无处不在。作者花了很大的篇幅来介绍这个模式,且在Binder中也存在代理模式的影子,之后需要再仔细读读。


    References

    展开全文
  • Android 代理自动配置PAC研究

    千次阅读 2018-02-26 09:16:25
    Android 代理自动配置PAC研究 环境 小米6 MIUI9.2 Android7.1.1 MacOS 10.13.3 Charles 4.0.2 什么是PAC PAC,全称Proxy Auto Config,中文名代理自动配置。PAC类似于配置文件,通过这个配置文件,浏览器或者其他...
  • 如何用安卓手机做代理服务器

    千次阅读 2021-05-31 10:42:48
    之前看过安卓手机上有一款叫做every proxy的app。可以直接将手机变成http代理服务器。不过装上去以后立马发现一个问题。 此处的ip居然是http://10.170.xxx.xxx多年的经验告诉我,这是一个内网ip。果然经过测试。...
  • android 代理设置

    2012-12-26 11:54:05
    android 手机端 代理设置,可以设置局域网内的pc,然后在pc上抓包,便于调试
  • Android 代理服务器为全网提供代理 背景:学校WiFI过滤较严,故学生很少有可以上网账号的。而学校又分为俩层验证,第一层可以注册并且拥有访问校内网的权限,第二层为校内密码验证机(非服务器)进行用户密码验证。...
  • 同样的操作有的时候一天甚至要操作上10次,不用的时候还得关闭,不关闭有些软件还使用不了,那么现在就有一款神器,WiFi代理设置是基于Auto.js无障碍开发的安卓端一键自动设置WiFi代理的APP,配合Fiddler、Burp、...
  • 67.[开源][安卓][全局代理]proxydroid-master

    千次下载 热门讨论 2015-03-01 11:07:13
    67.[开源][安卓][全局代理]proxydroid-master ProxyDroid是Android上的一个全局代理应用,遵循GPLv3协议,可以帮助你设置Android设备上的代理。proxydroid项目包含了ProxyDroid所有开放源代码。
  • [963]Android app代理软件

    千次阅读 2021-04-27 22:06:12
    文章目录VNET——最好用的Android抓包神器proxydroid软件特色proxydroid简单的设置方法 VNET——最好用的Android抓包神器 VNET是Android平台下功能最强大的网络抓包工具,支持HTTP&HTTPS,TCP&UDP,IPv6&...
  • 使用代理下载android系统源码和SDK ** 谷歌被墙后,如何下载android源码和sdk?使用代理。步骤如下: 寻找可用代理 先在这里找一个可用的代理服务器:http://www.xici.net.co/,我用的是 72.64.146.136 3128 HTTP ...
  • Unity 与 Android 使用 AndroidJavaProxy 交互类似代理委托(aar包) 1、Android 定义 接口 interface,并有设置实例化接口的函数,然后 打包 aar 2、导入 Unity,然后 public class TestInterface : ...
  • 一款依赖神经网络控制代理安卓模拟游戏,大量使用![LibGDX] ( )。 该分支构建了整个模拟的基本架构,以及运行不同神经网络的测试平台。 参观 查看当前神经网络代理训练的方法! 使用创建的代理示例 使用创建的...
  • 打开Android Studio并从中启动Android SDK管理器(“工具”>“ Android”>“ SDK Manager”) 检查是否已安装这两个组件并将其更新为最新版本。 如有必要,请安装或升级它们。 Android SDK平台工具 Android支持库 ...
  • 适用于Android和Java的简易代理 适用于android和java应用程序的Easy Proxy。 在那些只希望为您的应用程序代理的日子里。 为不同的URL支持不同的代理。 我们都知道这是多么痛苦: 进入wifi->长按wifi->修改网络->...
  • Android手机sock5代理免root

    千次阅读 2021-10-22 23:48:26
    Postern Postern Sotftware LabCommunication 使用: https://play.google.com/store/apps/details?id=com.tunnelworkshop.posternhttps://play.google.com/store/apps/details?id=com.tunnelworkshop.postern... ...
  • AndroidAgent OCS库存NG Android代理网站: :
  • 2 安卓端的wifi设置到提示的ip及其端口,安装证书后,此时安卓端请求能被Charles代理解析到 访问 chrl.pro/ssl 进行安卓端的证书安装(建议chrome,访问网址即自动下载安装证书) 3 进行域名转发,Map...
  • Android中的代理模式

    2022-02-07 16:57:57
    Android中的代理模式 1. 什么是代理 比如我们生活中的找出租屋,需要去找中介进行寻找挑选. 而这里的中介就是代理. 列子中看出代理特点如下 1. 租客跟中介要做成的最终目的是一致的就是租到房子(目标一致). 2....
  • Android 使用Charles 抓https包,需要安装证书。 证书地址: http://www.charlesproxy.com/getssl 注意: 下载完成,yi b ban
  • android检测代理,防止别人抓包

    千次阅读 2021-07-26 10:29:06
    APP在发起网络请求前会检测系统是否设置了代理,如果发现有代理,就不发起请求。以下是一段APP检测系统是否有代理的实例代码: public static boolean isWifiProxy(Context context) { final boolean IS_ICS_OR_...
  • Charles android手机配置代理

    千次阅读 2019-05-08 13:32:36
    [移动开发]Android应用发展趋势必备武器 热修复与插件化] 6-13 项目中集成Tinker 这一章中有关于Charles的使用介绍,可以参考 以我的华为Mate7为例: 我们在调试移动APP时,需要抓取APP发送的数据包,首先进行...
  • Android设备设置代理的两种方法

    万次阅读 热门讨论 2019-06-11 17:21:18
    本文将介绍两种给给android设备设置网络代理的方法,一种是直接在网络设置中操作,另一种是通过adb指令操作 第一种最常用的通过设置页面操作(此处以夜神模拟器为例讲解,其他设备操作方式基本类似) 操作路径:...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 103,185
精华内容 41,274
关键字:

安卓代理