IOC(Inversion of Control):控制反转。采用配置文件和注解的方式,将成员变量通过反射注入,舍弃new的方式,降低了耦合度。

反射:JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。Java反射机制主要提供了以下功能: 在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。

注解:注解的实现依赖于反射。JAVA中的注解是一种继承自接口java.lang.annotation.Annotation的特殊接口。通过动态代理的方式为你生成了一个实现了接口Annotation的实例,然后对该代理实例的属性赋值,这样就可以在程序运行时(如果将注解设置为运行时可见的话)通过反射获取到注解的配置信息。

常见IOC框架:Afinal,Xutils,Annotations,ButterKnife,Dagger,RoboGuice等。

注解写法比较:

  未加注解写法:

public class MainActivity extends Activity {
TextView textView; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.text);
textView.setText("test"); textView.setOnClickListener(new OnClickListener() { @Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent = new Intent(this, ChildActivity.class);
startActivity(intent);
}
});
}
}

  Android Annotations写法:

@EActivity(R.layout.activity_main)
public class MainActivity extends Activity {
@ViewById(R.id.text)
TextView textView; @AfterViews
public void init() {
textView.setText("annotations test");
} @Click(R.id.text)
void buttonClick() {
Intent intent = new Intent(this,ChildActivity_.class);
startActivity(intent);
}
}

其他语法举例

色值 @ColorRes

  @ColorRes(R.color.backgroundColor)
int someColor; @ColorRes
int backgroundColor;

动画 @AnimationRes

  @AnimationRes(R.anim.fadein)
XmlResourceParser xmlResAnim; @AnimationRes
Animation fadein;

自定义View @EViewGroup

@EViewGroup(R.layout.title_with_subtitle)
public class TitleWithSubtitle extends RelativeLayout { @ViewById
protected TextView title, subtitle; public TitleWithSubtitle(Context context, AttributeSet attrs) {
super(context, attrs);
} public void setTexts(String titleText, String subTitleText) {
title.setText(titleText);
subtitle.setText(subTitleText);
} }

HttpClient @HttpsClient

@HttpsClient
HttpClient httpsClient;

UiThread @UiThread

void myMethod() {
doInUiThread("hello", 100);
} @UiThread
void doInUiThread(String aParam, long anotherParam) {
[...]
}

Android Annotations的实现原理

  使用标准的Java注解处理工具自动添加一个额外的编译步骤生成的源代码。其实就是生成一个原有类的子类,这个子类才是真正运行用的类。

  该子类重载一些方法(例如onCreate()),通过委托方式调用了activity的相关方法。所以这里有个大坑,所有Activity的相关操作都要操作其子类,例如 AndroidManifest.xml中类名要写成android:name=".MainActivity_",开启MainActivity要写成 startActivity(new Intent(this, MainActivity_.class));下面是上文中AndroidAnnotations方式写法的MainActivity的子类MainActivity_

ButterKnife

常规写法

public class MainActivity extends Activity {
TextView textView;
ListView listView;
ListViewAdapter adapter; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.text);
listView = (ListView) findViewById(R.id.ListView);
textView.setText("test");
adapter = new ListViewAdapter(MainActivity.this);
listView.setAdapter(adapter);
textView.setOnClickListener(new OnClickListener() { @Override
public void onClick(View v) {
text.setText("你点击了按钮");
}
});
} class ListViewAdapter extends BaseAdapter { private Context mContext; public ListViewAdapter(Context context) {
mContext = context;
} @Override
public int getCount() {
// TODO Auto-generated method stub
return 1000;
} @Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return position;
} @Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
} @Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if (convertView == null) {
holder = new ViewHolder();
LayoutInflater layoutInflater = ((Activity) mContext)
.getLayoutInflater();
convertView = layoutInflater.inflate(R.layout.list_item,
parent, false);
holder.imageview = (ImageView) convertView
.findViewById(R.id.headshow);
holder.textview0 = (TextView) convertView
.findViewById(R.id.name);
holder.textview1 = (TextView) convertView
.findViewById(R.id.text);
convertView.setTag(convertView);
} else {
convertView = (View) convertView.getTag();
}
holder.textview0.setText("star");
holder.textview1.setText("test");
return convertView;
} } static class ViewHolder {
ImageView imageview;
TextView textview0;
TextView textview1;
}
}

ButterKnife写法

public class MainActivity extends Activity {

    @InjectView(R.id.text)
TextView text; @InjectView(R.id.ListView)
ListView listView; ListViewAdapter adapter; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.inject(this);
adapter = new ListViewAdapter(MainActivity.this);
listView.setAdapter(adapter);
text.setText("ButterKnife test");
} @OnClick(R.id.text)
void onClick() {
text.setText("你点击了按钮");
} class ListViewAdapter extends BaseAdapter {
private Context mContext; public ListViewAdapter(Context context) {
mContext = context;
} @Override
public int getCount() {
// TODO Auto-generated method stub
return 1000;
} @Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return position;
} @Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
} @Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if (convertView == null) {
LayoutInflater layoutInflater = ((Activity) mContext)
.getLayoutInflater();
convertView = layoutInflater.inflate(
R.layout.list_item, parent, false);
holder = new ViewHolder(convertView);
convertView.setTag(convertView);
} else {
convertView = (View) convertView.getTag();
}
holder.textview0.setText("butterknife");
holder.textview1.setText("test");
return convertView;
} } static class ViewHolder {
@InjectView(R.id.headshow)
ImageView imageview;
@InjectView(R.id.name)
TextView textview0;
@InjectView(R.id.text)
TextView textview1;
public ViewHolder(View view) {
ButterKnife.inject(this, view);
}
}
}
ButterKnife其他语法列举

资源注入

class ExampleActivity extends Activity {
@BindString(R.string.title) String title;
@BindDrawable(R.drawable.graphic) Drawable graphic;
@BindColor(R.color.red) int red;
@BindDimen(R.dimen.spacer) Float spacer;
// ...
}

Fragment注入

public class FancyFragment extends Fragment {
@InjectView(R.id.button1) Button button1;
@InjectView(R.id.button2) Button button2; @Override View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fancy_fragment, container, false);
ButterKnife.inject(this, view);
// TODO Use "injected" views...
return view;
}
}

回调函数注入

// 带有 Button 参数
@OnClick(R.id.submit)
public void sayHi(Button button) {
button.setText("Hello!");
} // 不带参数
@OnClick(R.id.submit)
public void submit() {
// TODO submit data to server...
} // 同时注入多个 View 事件
@OnClick({ R.id.door1, R.id.door2, R.id.door3 })
public void pickDoor(DoorView door) {
if (door.hasPrizeBehind()) {
Toast.makeText(this, "You win!", LENGTH_SHORT).show();
} else {
Toast.makeText(this, "Try again", LENGTH_SHORT).show();
}
}

  实现原理上ButterKnife的实现也是在编译的过程中生成了另外一个类来帮我们完成一些基本操作,生成了一个名为MainActivity$$ViewInjector的类。但与Android Annotations所不同的是,我们在代码中操作的还是MainActivity,而并不是MainActivity$$ViewInjector。

注解反射原理(IOC框架)的更多相关文章

  1. java框架之Spring(2)-注解配置IOC&AOP配置

    注解配置IoC 准备 1.要使用注解方式配置 IoC,除了之前引入的基础 jar 包,还需要引入 spring-aop 支持包,如下: 2.在 applicationContext.xml 中引入 c ...

  2. 10 Spring框架--基于注解的IOC配置

    1.工程环境搭建 2.基于注解的IOC配置 IOC注解的分类 (1)用于创建对象的 他们的作用就和在XML配置文件中编写一个<bean>标签实现的功能是一样的@Component: 作用: ...

  3. IOC框架

    一. IOC理论的背景 我们都知道,在采用面向对象方法设计的软件系统中,它的底层实现都是由N个对象组成的,所有的对象通过彼此的合作,最终实现系统的业务逻辑. 图1:软件系统中耦合的对象 如果我们打开机 ...

  4. Android 进阶 Android 中的 IOC 框架 【ViewInject】 (下)

    上一篇博客我们已经带大家简单的吹了一下IoC,实现了Activity中View的布局以及控件的注入,如果你不了解,请参考:Android 进阶 教你打造 Android 中的 IOC 框架 [View ...

  5. Android 进阶Android 中的 IOC 框架 【ViewInject】 (上)

    1.概述 首先我们来吹吹牛,什么叫IoC,控制反转(Inversion of Control,英文缩写为IoC),什么意思呢? 就是你一个类里面需要用到很多个成员变量,传统的写法,你要用这些成员变量, ...

  6. 【Android开发经验】来,咱们自己写一个Android的IOC框架!

    到眼下位置.afinal开发框架也是用了好几个月了,还记得第一次使用凝视完毕控件的初始化和事件绑定的时候,当时的心情是多么的兴奋- -代码居然能够这样写!然后随着不断的学习,也慢慢的对IOC框架和注解 ...

  7. 自己动手编写IOC框架(四)

    终于到了激动人心的时刻了,首先感谢小伙伴们的阅读,如果能多点评论,多点探讨就更好了,没有交流让我觉得我写的东西只有标题有点价值,内容只是在浪费大家的时间.为了泪滴下周能写下一个框架orm,请小伙伴们能 ...

  8. 自己动手编写IOC框架(一)

    博客创建了2年多了,一直没敢写点东西,怕技术不够误导了别人.2年多后的今天我已经很有信心能够为需要帮助的人做点微薄的贡献了.这是我第一次写博客,先自我介绍一下.本人网名泪滴,一个非常伤心的名字,生活中 ...

  9. Android 进阶 教你打造 Android 中的 IOC 框架 【ViewInject】 (下)

    上一篇博客我们已经带大家简单的吹了一下IoC,实现了Activity中View的布局以及控件的注入,如果你不了解,请参考:Android 进阶 教你打造 Android 中的 IOC 框架 [View ...

随机推荐

  1. jz2440-uboot-201204版本移植【学习笔记】【原创】

    平台:jz2440 作者:庄泽彬(欢迎转载,请注明作者) 说明:韦东山二期视频学习笔记 交叉编译工具:arm-linux-gcc (GCC)4.3.2 PC环境:ubuntu18.04 一.uboot ...

  2. hdu_2048 错排问题

    错排问题本质上就是一个动态规划问题,其状态转移方程为: 记d[n]为n个人错排情况的总数. 那么策略可以描述为:分析第n个人错排的可能情况: 1)前n-1个人满足错排的情况,那么第n个人加入后还要错排 ...

  3. 转:常用svn命令

    在公司需要提交代码,常用的就是co.ci.add.up.和log 首先 svn help 可以看到 svn 所支持的全部命令: 命令不多,如果用过Tortoise SVN的客户端,从字面上也不难理解这 ...

  4. HDU 1503 Advanced Fruits(LCS+记录路径)

    http://acm.hdu.edu.cn/showproblem.php?pid=1503 题意: 给出两个串,现在要确定一个尽量短的串,使得该串的子串包含了题目所给的两个串. 思路: 这道题目就是 ...

  5. c++ 插入容器元素(insert)

    #include <iostream> #include <vector> using namespace std; int main () { vector<int&g ...

  6. 【源码学习之spark streaming 1.6.1 】

    说明:个人原创,转载请说明出处 http://www.cnblogs.com/piaolingzxh/p/5634577.html 未完待续

  7. Spring 及 SpringMVC的web.xml配置详解

    出处http://blog.csdn.net/u010796790 1.spring 框架解决字符串编码问题:过滤器 CharacterEncodingFilter(filter-name) 2.在w ...

  8. UVA-12166 Equilibrium Mobile(二叉树)

    题目大意:改变二叉树上的权值,使树平衡,问最少该几个值. 题目分析:不会做,查的题解.有条奇妙的性质:如果将第d层权值为w的节点为基准做改动,则整棵树的总重量为w<<d,即w*2^d.仔细 ...

  9. UVA-127 "Accordian" Patience (模拟)

    题目大意:一种纸牌游戏,将52张扑克牌排成一列,每次操作可将一张扑克牌移到它的前一张或前面第三张上当牌的点数或花色匹配时.每次都移动最靠左的扑克牌,并且能移动三格就移动三格.求最终扑克牌状态. 题目分 ...

  10. 201621123010《Java程序设计》第5周学习总结

    1. 本周学习总结 1.1 写出你认为本周学习中比较重要的知识点关键词 接口.面向接口编程 interface.implements has-a 关系 Comparable.Comparator 1. ...