动态接口实现网络加载

1.要实现动态接口必须了解几个定义:

  • 注解:
    定义注解(Annotation),也叫元数据。一种代码级别的说明。它是JDK1.5及以后版本引入的一个特性,与类、接口、枚举是在同一个层次。它可以声明在包、类、字段、方法、局部变量、方法参数等的前面,用来对这些元素进行说明,注释。
    元注解:负责描述注解的注解
    1.@Target :标记注解用于描述什么,可以使方法,属性等等…
    2.@Retention:定义注解保留的时间
    3.@Documented:用于描述其它类型的annotation应该被作为被标注的程序成员的公共API,因此可以被例如javadoc此类的工具文档化。Documented是一个标记注解,没有成员。
    4.@Inherited:元注解是一个标记注解,@Inherited阐述了某个被标注的类型是被继承的。如果一个使用了@Inherited修饰的annotation类型被用于一个class,则这个annotation将被用于该class的子类。

    1. 反射:通过.class类的描述类,直接生成对象,直接查找修改类的属性,方法,静态变量.

    2.动态接口

    目标:在通过网络 访问数据接口,并且对返回的json处理,添加在安卓控件过程中,封装一个工具类,将需要传递的url写在一个自定义的接口(内含一个传参方法)里传入(通过注解传入固定不变的部分,通过接口中某个方法传递进一个可变参数),通过工具类实例化接口,并在调用接口方法的时候执行代理invoke方法,实现网络加载,具体代码如下.

    1. 代理类:
public class Tools {
    public static<T> T getInstance(Class<T> type){
        Object o = Proxy.newProxyInstance(type.getClassLoader(), new Class[]{type}, new MyHandler());
        return ((T) o);
    }


    private static class MyHandler implements InvocationHandler{
        /**
         * invoke 方法在生成的接口对象调用其中方法的时候调用
         * @param proxy   代理:通过代理把下面方法加载进去
         * @param method   要加载的方法
         * @param args     要加载的方法的参数
         * @return
         * @throws Throwable
         */
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            UrlString annotation = method.getAnnotation(UrlString.class);
            if (annotation != null) {
                String url = String.format(Locale.CHINA, annotation.value(), args);
                Class<?> returnType = method.getReturnType();
                if (returnType.equals(DownWebTask.class)) {
                    ParameterizedType type = (ParameterizedType) method.getGenericReturnType();
                    Type entryType = type.getActualTypeArguments()[0];
                    return new DownWebTask<>(url, ((Class) entryType));
                }
            }
            return null;
        }
    }

}

2.网络加载工具:

public class DownWebTask<T> extends AsyncTask<DownWebTask.Callback<T>,Void,Object> {
    private static final String TAG = DownWebTask.class.getSimpleName();
    //传入参数     中间过程数据   返回值
    private String url;
    private Callback callback;
    private Class<T> t;
    public interface Callback<S>{
        void onSuccess(S t);
        void onFail(Exception e);
    }

    public DownWebTask(String url, Class<T> t) {
        this.url = url;
        this.t = t;
    }

    @Override
    protected Object doInBackground(Callback<T>... params) {
        callback=params[0];
        try {
            HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
            connection.setRequestMethod("GET");
            connection.setDoInput(true);
            int responseCode = connection.getResponseCode();
            if (responseCode==200){
                InputStream inputStream = connection.getInputStream();
                ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
                int len;
                byte[] bytes = new byte[102400];
                while ((len=inputStream.read(bytes))!=-1){
                    byteArrayOutputStream.write(bytes, 0, len);
                }
                String s = byteArrayOutputStream.toString("UTF-8");
//                Log.d(TAG, "doInBackground: "+s);
                return new Gson().fromJson(s,t);
            }else {
                return new RuntimeException("网络错误,responseCode "+responseCode);
            }
        } catch (IOException e) {
            return e;
        }
    }

    @Override
    protected void onPostExecute(Object o) {
        super.onPostExecute(o);
        if (t.isInstance(o)){
            callback.onSuccess(((T) o));
        }else if (o instanceof Exception){
            callback.onFail(((Exception) o));
        }
    }

}

3.自定义注解(用于修饰自己的接口)

//修饰注解的注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface UrlString {
    String value();
}

4.数据实体类

public class Entry {
    @SerializedName("message")
    private String message;

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

5.主程序

public class MainActivity extends AppCompatActivity implements DownWebTask.Callback<Entry>{

    private TextView mTextView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mTextView = (TextView) findViewById(R.id.text);
        Object instance = Tools.getInstance(DataInterface.class);
        ((DataInterface) instance).getShow(9987).execute(this);
    }


    @Override
    public void onSuccess(Entry t) {
        mTextView.setText(t.getMessage());
    }

    @Override
    public void onFail(Exception e) {
        Toast.makeText(MainActivity.this, "网络异常", Toast.LENGTH_SHORT).show();
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值