[置顶] 注解在android中的使用

注解在android程序中的使用

何为注解:

在Java当中,注解又叫做“元数据”,它为我们在源代码中添加信息提供了一种形式化的方法,让我们能在以后的某个时间方便的使用这些数据。更确切的说,注解在一定的程度上将数据与元代码进行了绑定,并不是将数据保存在外部文件中。当然,这里只介绍Android开发相关的技术,至于注解我会在Java学习总结篇中进行详细的研究和总结。那么,接下来我们一个实例来介绍注解在android开发中的巧妙应用。

实例描述:

在这里,我们使用注解替换掉android中初始化资源对象的findViewById(...)方式,具体如下代码所示:

我的项目结构:

 [置顶] 注解在android中的使用_第1张图片

注解部分:

ContentView.java:

/**

 * inject contentview

 */

@Target(ElementType.TYPE)

@Retention(RetentionPolicy.RUNTIME)

public @interface ContentView {

int value() default 0;

}

 

InjectView.java:

/**

 * inject view of contentview

 */

@Target(ElementType.FIELD)

@Retention(RetentionPolicy.RUNTIME)

public @interface ViewInject {

int value();

int parentResId() default 0;

}

 

资源初始化部分:

ViewInjectObj.java:

int parentResId;

Object value;

@Override

public boolean equals(Object obj) {

boolean result;

if(this == obj) {

result = true;

}

if(!(obj instanceof ViewInjectObj)) {

result = false;

}

ViewInjectObj that = (ViewInjectObj) obj;

if(parentResId != that.parentResId) {

result = false;

}

if(null == value) {

return result = (null == that.value);

}

result = value.equals(that.value);

return result;

}

@Override

public int hashCode() {

int result = value.hashCode();

result = 35 * result + parentResId;

return result;

}

 

@Override

public String toString() {

return "ViewInjectObj [parentResId=" + parentResId + ", value=" + value

"]";

}

 

ViewSelector.java:

/**

 * find view id resources

 */

public class ViewSelector {

private Activity currActivity;

private View currView;

public ViewSelector(Activity activity) {

currActivity = activity;

}

public ViewSelector(View view) {

currView = view;

}

public View findViewById(int id) {

return null == currView ? currActivity.findViewById(id) : currView.findViewById(id);

}

    public View findViewByInfo(ViewInjectObj info) {

        return findViewById((Integer) info.value, info.parentResId);

    }

public View findViewById(int id,int pId) {

View pView = null;

if(0 < pId) {

pView = findViewById(pId);

}

View currView = null;

if(null != pView) {

currView = pView.findViewById(id);

else {

currView = findViewById(id);

}

return currView;

}

}

 

映射方法部分:

InjectConfig.java:

/**

 * inject view methods

 */

public class InjectConfig {

static final String TAG = "InjectConfig";

public InjectConfig() {

}

// inject contentview 

public void injectContentView(Object obj,Class<?> objClass) {

ContentView contentView = objClass.getAnnotation(ContentView.class);

if(null != contentView) {

try {

Method method = objClass.getMethod("setContentView"int.class);

method.invoke(obj, contentView.value());

catch(Throwable tr) {

Log.e(TAG, tr.getMessage(), tr);

}

}

}

// inject view 

public void injectView(Object obj,ViewSelector viewSelector,Class<?> objClass) {

Field[] fields = objClass.getDeclaredFields();

if(null != fields && 0 < fields.length) {

for(Field field : fields) {

ViewInject viewInject = field.getAnnotation(ViewInject.class);

if(null != viewInject) {

try {

View view = viewSelector.findViewById(viewInject.value(), viewInject.parentResId());

if(null != view) {

field.setAccessible(true);

field.set(obj, view);

}

catch(Throwable tr) {

Log.e(TAG, tr.getMessage(), tr);

}

}

}

}

}

}

 

调用工具部分:

ViewUtilSvc.java:

public class ViewUtilSvc {

static InjectConfig config = null;

public static void inject(Activity activity) {

inject(activity,new ViewSelector(activity));

}

public static void inject(View view) {

inject(view,new ViewSelector(view));

}

    public static void inject(Object obj, View view) {

        inject(obj, new ViewSelector(view));

    }

static void inject(Object obj,ViewSelector viewSelector) {

if(null == config) {

config = new InjectConfig();

}

Class<?> objClass = obj.getClass();

config.injectContentView(obj, objClass);

config.injectView(obj, viewSelector, objClass);

}

}

 

前台显示部分:

MainActivity.java:

@ContentView(R.layout.activity_main)

public class MainActivity extends FragmentActivity {

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

// setContentView(R.layout.activity_main);

ViewUtilSvc.inject(this);

if (savedInstanceState == null) {

getSupportFragmentManager()

.beginTransaction()

.add(R.id.containernew PlaceholderFragment())

.commit();

}

}

 

public static class PlaceholderFragment extends Fragment {

@ViewInject(R.id.tvHelloWorld)

TextView tvHelloWorld;

public PlaceholderFragment() {

}

 

@Override

public View onCreateView(LayoutInflater inflater, ViewGroup container,

Bundle savedInstanceState) {

View rootView = inflater.inflate(R.layout.fragment_main, container,false);

ViewUtilSvc.inject(this,rootView);

String hello = getResources().getString(R.string.text_helloworld_tv);

tvHelloWorld.setText(hello);

return rootView;

}

}

 

}

 

正如上面代码所示,我们使用了注解在代码中动态的添加了数据,然后借助反射机制来获得注解的数据;

使用了@ContentView(...) 替代了原生的setContentView(...)部分,使用了ViewUtilSvc.inject(...)进行对应的注射即可。另外,这样的做的目的就是为了简化对象视图的初始化工作。具体的运行效果图如下所示:

 [置顶] 注解在android中的使用_第2张图片

 

好了,到这里我们的TextView上的hello world终于显示出来了,如果有任何问题的话,请在评论中进行发问讨论。

 

/**

* 技术交流QQ群179914858

*/

你可能感兴趣的:(android)