android——框架的实现系列(资源的依赖注入)

               原创文章,转载请注明

               实现目标

               我们知道,android通过R类对资源进行管理,每个资源对应一个整型数字。那么如果我们能够通过注释指定该整型数字就能获得资源对象就好了。比如如下所示:

@Resource(value=R.id.common_time)
	private ListView listView;

              我们知道,每个界面,不论activity或者fragment都需要对应一个layout资源文件,那么这个关系是否也能通过注释指定呢?,比如如下所示:

@Layout(value=R.layout.activity_main)
public class MainActivity extends BaseActivity

              实现方法

              如何实现我们的目标呢?

              这两个目标的实现相对前面两篇文章中的目标还是比较简单的,无非是通过反射去获取是否有该注释,如果有的话通过相应方法返回对象即可。

              1、BaseFragment类

              需要进行资源依赖注入的fragment必须继承该类

              对于@Layout的实现

              a、在该类的public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState)方法中实现

              b、判断自己是否有@Layout注释,如果有的话获得该注释的value,这样就获得资源id了

              c、调用inflater.inflate(资源id, container, false) 就将layout资源文件和fragment绑定了


              对于@Resource的实现

              a、在该类的 View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState)方法中实现

              b、通过反射自己的成员变量,判断成员变量是否有@Resource注释,如果有的话获得该注释的value,这样就获得资源id了

              c、调用View v=layout.findViewById(资源id)获得资源对象,注意layout为@Layout实现中调用inflate方法返回的对象。最后把该view对象赋值给该成员变量即可


             2、BaseActivity类

             该类和上面的类大同小异,只不过是在void onCreate(Bundle savedInstanceState)方法实现罢了


             看一下代码吧

             BaseFragment类

             其中有控制跳转的代码,LayoutFactory类,AALayout类,可以无视掉

public class BaseFragment extends BackHandledFragment {
	
	private Map<String,Object> fieldMap;
	
	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
		Context context = getActivity();
		Bundle bundle = this.getArguments();
		//通过position获得指定的界面
		position = (String) bundle.get("position");
		View layout = null;
		try {
			Class<?> cls=Class.forName(position);
			AALayout aalayout;
			if(fieldMap!=null){
				aalayout = LayoutFactory.create(cls,fieldMap);
			}
			else{
				aalayout = LayoutFactory.create(cls);
			}
			
			//获取布局资源,依赖注入资源
			Class<?> acls=aalayout.getClass();
			//获取layout资源
			if(acls.isAnnotationPresent(Layout.class)){
				Layout layoutAnno=acls.getAnnotation(Layout.class);
				int layoutXmlId=layoutAnno.value();
				layout = inflater.inflate(layoutXmlId, container, false);
				Field[] fields=cls.getDeclaredFields();
				for(Field field : fields){
					Class<?> fcls=field.getType();
					if(View.class.isAssignableFrom(fcls)){
						//获取Resource资源
						if(field.isAnnotationPresent(Resource.class) && !Modifier.isStatic(field.getModifiers())){
							field.setAccessible(true);
							Resource resource=field.getAnnotation(Resource.class);
							int rid=resource.value();
							View v=layout.findViewById(rid);
							field.set(aalayout, v);
						}
					}
				}
			}
			//相当于页面跳转
			aalayout.getLayout(inflater,container,savedInstanceState,context,bundle);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 
		return layout;
	}

	@Override
	public boolean onBackPressed() {
		return false;
	}

	public void setFieldMap(Map<String, Object> fieldMap) {
		this.fieldMap = fieldMap;
	}
	
}


               BaseActivity类

               该类中有控制跳转的代码,@Root注释,BackHandledInterface接口,可以无视掉

public class BaseActivity extends FragmentActivity implements BackHandledInterface{

	protected BackHandledFragment mBackHandedFragment;  
	public static DBHelper helper;
	protected boolean isRoot=true;
	private int xmlId;
	private int layoutId;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		//框架入口,进行类容器,实例容器,数据库映射工具初始化
		LoadHelper.init();
		Class<?> cls=getClass();
		String childClassName=cls.getSimpleName();
		if(childClassName!=null)
		//解析root注释,获得入口资源id
		try {
			if(cls.isAnnotationPresent(Root.class)){
				Root root=cls.getAnnotation(Root.class);
				xmlId=root.xml_id();
			}
			//获得布局资源
			if(cls.isAnnotationPresent(Layout.class)){
				Layout layout=cls.getAnnotation(Layout.class);
				layoutId=layout.value();
				setContentView(layoutId);
			}
			//依赖注入资源
			Field[] fields=cls.getDeclaredFields();
			for(Field field : fields){
				Class<?> fcls=field.getType();
				if(View.class.isAssignableFrom(fcls)){
					if(field.isAnnotationPresent(Resource.class) && !Modifier.isStatic(field.getModifiers())){
						field.setAccessible(true);
						Resource resource=field.getAnnotation(Resource.class);
						int rid=resource.value();
						Method m=cls.getMethod("findViewById", int.class);
						View v=(View) m.invoke(this, rid);
						field.set(this, v);
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		super.onCreate(savedInstanceState);
	}
	
	@Override
	public void onDestroy(){
		super.onDestroy();
		if(helper!=null){
			helper.close();
		}
	}
	
	@Override
	public void setSelectedFragment(BackHandledFragment selectedFragment) {
		this.mBackHandedFragment = selectedFragment;  
	}

	@Override
	public void setIsRoot(boolean flag) {
		this.isRoot=flag;
	}
	
	public void setmBackHandedFragment(BackHandledFragment mBackHandedFragment) {
		this.mBackHandedFragment = mBackHandedFragment;
	}
	
	public void routeFromRoot(String position,Map<String,Object> args){
		if(isRoot){
			if(getFragmentManager().getBackStackEntryCount() == 1)
        		isRoot=true;
        	else
        		isRoot=false;
			route(position,args);
		}
	}
	
	public void routeFromOthers(String position,Map<String,Object> args){
		isRoot=false;
		route(position,args);
	}
	
	private void route(String position,Map<String,Object> args){
		BaseFragment baseFragment = new BaseFragment();
		/*
		if(this instanceof Activity)
			baseFragment.setFieldMap(getExtraField());
		*/
		mBackHandedFragment=baseFragment;
        Bundle bundle = new Bundle();
        bundle.putString("position", position);
        if(args!=null){
	        for(Map.Entry<String, Object> argEntry : args.entrySet()){
	        	Object arg=argEntry.getValue();
	        	if(arg instanceof String){
	        		bundle.putString(argEntry.getKey(), (String) arg);
	        	}
	        	else if(arg instanceof Integer){
	        		bundle.putInt(argEntry.getKey(), (Integer) arg);
	        	}
	        	else if(arg instanceof Long){
	        		bundle.putLong(argEntry.getKey(), (Long) arg);
	        	}
	        	else if(arg instanceof Float){
	        		bundle.putFloat(argEntry.getKey(), (Float) arg);
	        	}
	        	else if(arg instanceof Double){
	        		bundle.putDouble(argEntry.getKey(), (Double) arg);
	        	}
	        	else if(arg instanceof Boolean){
	        		bundle.putBoolean(argEntry.getKey(), (Boolean) arg);
	        	}
	        	else if(arg instanceof Serializable){
	        		bundle.putSerializable(argEntry.getKey(), (Serializable) arg);
	        	}
	        	else if(arg instanceof IBinder){
	        		bundle.putBinder(argEntry.getKey(), (IBinder) arg);
	        	}
	        	else if(arg instanceof Bundle){
	        		bundle.putAll((Bundle) arg);
	        	}
	        }
        }
        baseFragment.setArguments(bundle);
        getFragmentManager().beginTransaction().replace(xmlId,baseFragment)
        									   .addToBackStack(null)
        									   .commit();
	}
	
	@Override  
    public void onBackPressed(){
    	if(mBackHandedFragment == null || !mBackHandedFragment.onBackPressed()){  
            if(getFragmentManager().getBackStackEntryCount() == 0){  
                super.onBackPressed();  
            }else{  
            	if(getFragmentManager().getBackStackEntryCount() == 1)
            		isRoot=true;
            	else
            		isRoot=false;
            	getFragmentManager().popBackStack();  
            }  
        }  
    }
	
	@SuppressWarnings("rawtypes")
	protected void startService(Class service) {
         Intent i = new Intent(this, service);
         i.setFlags(32);
         //i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
         startService(i);  
	 }

}

               Resource注释类

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Resource {

	int value();
	
}

              Layout注释类

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Layout {

	int value();
	
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值