IOC,控制反转(Inversion of Control,英文缩写为IOC),其实就是反射加注解。
使用:
public class MainActivity extends AppCompatActivity {
@ViewById(R.id.tv_personally)
private TextView tv_personally;
private int count = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ViewUtils.inject(this);
tv_personally.setText("Hi IOC");
}
@OnClick({R.id.iv_personally, R.id.tv_personally})
@CheckNet // 检测网络
private void onClick(View view) {
switch (view.getId()) {
case R.id.iv_personally:
Toast.makeText(MainActivity.this, "点击了图片", Toast.LENGTH_LONG).show();
break;
case R.id.tv_personally:
count++;
tv_personally.setText(count + "");
break;
}
}
}
View属性注入
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ViewById {
int value();
}
/**
* View 的 findViewById的辅助类
*/
public class ViewFinder {
private Activity mActivity;
private View mView;
public ViewFinder(Activity activity) {
this.mActivity = activity;
}
public ViewFinder(View view) {
this.mView = view;
}
public View findViewById(int viewId) {
return mActivity != null ? mActivity.findViewById(viewId) : mView.findViewById(viewId);
}
public class ViewUtils {
public static void inject(Activity activity) {
inject(new ViewFinder(activity), activity);
}
public static void inject(View view) {
inject(new ViewFinder(view), view);
}
public static void inject(View view, Object object) {
inject(new ViewFinder(view), object);
}
//兼容上面三个方法 object:反射需要执行的类
private static void inject(ViewFinder finder, Object object) {
injectFiled(finder, object);
injectEvent(finder, object);
}
/**
* 注入View属性
*/
private static void injectFiled(ViewFinder finder, Object object) {
//1、获取类里面所有的属性
Class<?> clazz = object.getClass();
//获取所有属性包括私有和共有
Field[] fields = clazz.getDeclaredFields();
//2、获取ViewById里面的value值
for (Field field : fields) {
ViewById viewById = field.getAnnotation(ViewById.class);
if (viewById != null) {
//获取注解里面的id值 : R.id.tv_personally
int viewId = viewById.value();
//3、findViewById找到View
View view = finder.findViewById(viewId);
if (view != null) {
//能够注入所有的修饰符 包括private
field.setAccessible(true);
try {
//4、动态的注入找到的View(可以理解为给属性赋值)
field.set(object, view);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
}
}
点击事件注入
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface OnClick {
int[] value();
}
/**
* 点击事件注入
*/
private static void injectEvent(ViewFinder finder, Object object) {
//1、获取类里面所有的方法
Class<?> clazz = object.getClass();
//获取所有方法包括私有和共有
Method[] methods = clazz.getDeclaredMethods();
// 2.获取方法上面的所有id
for (Method method : methods) {
OnClick onClick = method.getAnnotation(OnClick.class);
if (onClick != null) {
int[] viewIds = onClick.value();
if (viewIds.length > 0) {
for (int viewId : viewIds) {
// 3.遍历所有的id 先findViewById然后 setOnClickListener
View view = finder.findViewById(viewId);
if (view != null) {
view.setOnClickListener(new DeclaredOnClickListener(method, object));
}
}
}
}
}
}
private static class DeclaredOnClickListener implements View.OnClickListener {
private Method mMethod;
private Object mHandlerType;
public DeclaredOnClickListener(Method method, Object handlerType) {
mMethod = method;
mHandlerType = handlerType;
}
@Override
public void onClick(View v) {
mMethod.setAccessible(true);
try {
// 4.反射执行方法
mMethod.invoke(mHandlerType, v);
} catch (Exception e) {
e.printStackTrace();
try {
mMethod.invoke(mHandlerType, null);
} catch (Exception e1) {
e1.printStackTrace();
}
}
}
}
扩展动态检测网络注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface CheckNet {
}
private static class DeclaredOnClickListener implements View.OnClickListener {
private Method mMethod;
private Object mHandlerType;
public DeclaredOnClickListener(Method method, Object handlerType) {
mMethod = method;
mHandlerType = handlerType;
}
@Override
public void onClick(View v) {
//新增此处
CheckNet checkNet = mMethod.getAnnotation(CheckNet.class);
if (checkNet!=null){
if (!isNetworkAvailable(v.getContext())){
Toast.makeText(v.getContext(), "没有网络呦", Toast.LENGTH_LONG).show();
return;
}
}
mMethod.setAccessible(true);
try {
// 4.反射执行方法
mMethod.invoke(mHandlerType, v);
} catch (Exception e) {
e.printStackTrace();
try {
mMethod.invoke(mHandlerType, null);
} catch (Exception e1) {
e1.printStackTrace();
}
}
}
}
/**
* 检查当前网络是否可用
*/
private static boolean isNetworkAvailable(Context context) {
// 获取手机所有连接管理对象(包括对wi-fi,net等连接的管理)
ConnectivityManager connectivityManager = (ConnectivityManager)
context.getSystemService(Context.CONNECTIVITY_SERVICE);
if (connectivityManager != null) {
// 获取NetworkInfo对象
NetworkInfo[] networkInfo = connectivityManager.getAllNetworkInfo();
if (networkInfo != null && networkInfo.length > 0) {
for (int i = 0; i < networkInfo.length; i++) {
// 判断当前网络状态是否为连接状态
if (networkInfo[i].getState() == NetworkInfo.State.CONNECTED) {
return true;
}
}
}
}
return false;
}
最后别忘了加上网络检测权限:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />