动态接口实现网络加载

来源:互联网 发布:中国人长相 知乎 编辑:程序博客网 时间:2024/05/19 01:14

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