Android IOC模块,利用了Java反射和Java注解

一、整体工程图

Android IOC模块,利用了Java反射和Java注解_第1张图片


二、BaseActivity.java

package com.jltxgcy.framework;
import android.os.Bundle;

public abstract class BaseActivity extends FrameActivity
{

	private String moduleName = "";
	private String layoutName = "";//main

	@Override
	protected void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		initActivity();
		onAfterOnCreate(savedInstanceState);
	}


	private void initActivity()
	{
		getModuleName();
		getLayoutName();
		initInjector();
		loadDefautLayout();
	}

	protected void onAfterOnCreate(Bundle savedInstanceState)
	{
		
	}

	private void initInjector()
	{
		getInjector().injectResource(this);
		getInjector().inject(this);
	}

	private void loadDefautLayout()
	{
		try
		{
			int layoutResID = getLayoutLoader().getLayoutID(
					layoutName);
			setContentView(layoutResID);
		} catch (Exception e)
		{
			e.printStackTrace();
		}
	}

	@Override
	public void setContentView(int layoutResID)
	{
		super.setContentView(layoutResID);
		getInjector().injectView(this);
		onAfterSetContentView();
	}


	protected void onAfterSetContentView()
	{

	}

	public String getModuleName()
	{
		String moduleName = this.moduleName;
		if (moduleName == null || moduleName.equalsIgnoreCase(""))
		{
			moduleName = getClass().getName().substring(0,
					getClass().getName().length() - 8);
			String arrays[] = moduleName.split("\\.");
			this.moduleName = moduleName = arrays[arrays.length - 1]
					.toLowerCase();
		}
		return moduleName;
	}

	public void setModuleName(String moduleName)
	{
		this.moduleName = moduleName;
	}

	public String getLayoutName()
	{
		String layoutName = this.layoutName;
		if (layoutName == null || layoutName.equalsIgnoreCase(""))
		{
			this.layoutName = this.moduleName;
		}
		return layoutName;
	}

	protected void setLayoutName(String layoutName)
	{
		this.layoutName = layoutName;
	}

}

三、FrameActivity.java

package com.jltxgcy.framework;





import android.app.Activity;

import com.jltxgcy.framework.annotation.Injector;
import com.jltxgcy.framework.layoutloader.ILayoutLoader;
import com.jltxgcy.framework.layoutloader.LayoutLoader;

public class FrameActivity extends Activity
{
	
	private ILayoutLoader mLayoutLoader;
	private Injector mInjector;

	public ILayoutLoader getLayoutLoader()
	{
		if (mLayoutLoader == null)
		{
			mLayoutLoader = LayoutLoader.getInstance(this);
		}
		return mLayoutLoader;
	}

	public void setLayoutLoader(ILayoutLoader layoutLoader)
	{
		this.mLayoutLoader = layoutLoader;
	}

	public Injector getInjector()
	{
		if (mInjector == null)
		{
			mInjector = Injector.getInstance();
		}
		return mInjector;
	}

	public void setInjector(Injector injector)
	{
		this.mInjector = injector;
	}
	

}

四、InjectObject.java

package com.jltxgcy.framework.annotation;

import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

@Retention(RUNTIME)
@Target(
{ ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
public @interface InjectObject
{
	boolean optional() default false;
}

五、InjectResource.java

package com.jltxgcy.framework.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(
{ ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
public @interface InjectResource
{
	int id() default -1;
}

六、InjectView.java

package com.jltxgcy.framework.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

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

	public int id() default -1;

	public String click() default "";

	public String longClick() default "";

	public String focuschange() default "";

	public String key() default "";

	public String Touch() default "";
}

七、Injector.java

package com.jltxgcy.framework.annotation;

import java.lang.reflect.Field;

import android.app.Activity;
import android.content.res.Resources;

public class Injector
{
	private static Injector instance;

	private Injector()
	{

	}

	public static Injector getInstance()
	{
		if (instance == null)
		{
			instance = new Injector();
		}
		return instance;
	}

	public void inJectAll(Activity activity)
	{
		// TODO Auto-generated method stub
		Field[] fields = activity.getClass().getDeclaredFields();
		if (fields != null && fields.length > 0)
		{
			for (Field field : fields)
			{
				if (field.isAnnotationPresent(InjectView.class))
				{
					injectView(activity, field);
				} else if (field.isAnnotationPresent(InjectResource.class))
				{
					injectResource(activity, field);
				} else if (field.isAnnotationPresent(InjectObject.class))
				{
					inject(activity, field);
				}
			}
		}
	}

	private void inject(Activity activity, Field field)
	{
		// TODO Auto-generated method stub
		try
		{
			field.setAccessible(true);
			field.set(activity, field.getType().newInstance());
		} catch (Exception e)
		{
			e.printStackTrace();
		}
	}

	private void injectView(Activity activity, Field field)
	{
		// TODO Auto-generated method stub
		if (field.isAnnotationPresent(InjectView.class))
		{
			InjectView viewInject = field.getAnnotation(InjectView.class);
			int viewId = viewInject.id();
			try
			{
				field.setAccessible(true);
				field.set(activity, activity.findViewById(viewId));
			} catch (Exception e)
			{
				e.printStackTrace();
			}
		}
	}

	private void injectResource(Activity activity, Field field)
	{
		// TODO Auto-generated method stub
		if (field.isAnnotationPresent(InjectResource.class))
		{
			InjectResource resourceJect = field
					.getAnnotation(InjectResource.class);
			int resourceID = resourceJect.id();
			try
			{
				field.setAccessible(true);
				Resources resources = activity.getResources();
				String type = resources.getResourceTypeName(resourceID);
				if (type.equalsIgnoreCase("string"))
				{
					field.set(activity,
							activity.getResources().getString(resourceID));
				} else if (type.equalsIgnoreCase("drawable"))
				{
					field.set(activity,
							activity.getResources().getDrawable(resourceID));
				} else if (type.equalsIgnoreCase("layout"))
				{
					field.set(activity,
							activity.getResources().getLayout(resourceID));
				} else if (type.equalsIgnoreCase("array"))
				{
					if (field.getType().equals(int[].class))
					{
						field.set(activity, activity.getResources()
								.getIntArray(resourceID));
					} else if (field.getType().equals(String[].class))
					{
						field.set(activity, activity.getResources()
								.getStringArray(resourceID));
					} else
					{
						field.set(activity, activity.getResources()
								.getStringArray(resourceID));
					}

				} else if (type.equalsIgnoreCase("color"))
				{
					if (field.getType().equals(Integer.TYPE))
					{
						field.set(activity,
								activity.getResources().getColor(resourceID));
					} else
					{
						field.set(activity, activity.getResources()
								.getColorStateList(resourceID));
					}

				}
			} catch (Exception e)
			{
				e.printStackTrace();
			}
		}
	}

	public void inject(Activity activity)
	{
		// TODO Auto-generated method stub
		Field[] fields = activity.getClass().getDeclaredFields();
		if (fields != null && fields.length > 0)
		{
			for (Field field : fields)
			{
				if (field.isAnnotationPresent(InjectObject.class))
				{
					inject(activity, field);
				}
			}
		}
	}

	public void injectView(Activity activity)
	{
		// TODO Auto-generated method stub
		Field[] fields = activity.getClass().getDeclaredFields();
		if (fields != null && fields.length > 0)
		{
			for (Field field : fields)
			{
				if (field.isAnnotationPresent(InjectView.class))
				{
					injectView(activity, field);
				}
			}
		}
	}

	public void injectResource(Activity activity)
	{
		// TODO Auto-generated method stub
		Field[] fields = activity.getClass().getDeclaredFields();
		if (fields != null && fields.length > 0)
		{
			for (Field field : fields)
			{
				if (field.isAnnotationPresent(InjectResource.class))
				{
					injectResource(activity, field);
				}
			}
		}
	}

}

八、ILayoutLoader.java

package com.jltxgcy.framework.layoutloader;

import android.content.pm.PackageManager.NameNotFoundException;

public interface ILayoutLoader
{
	public int getLayoutID(String resIDName) throws ClassNotFoundException,
			IllegalArgumentException, IllegalAccessException,
			NameNotFoundException;

}

九、LayoutLoader.java

package com.jltxgcy.framework.layoutloader;

import java.lang.reflect.Field;

import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.util.Log;

public class LayoutLoader implements ILayoutLoader
{

	private static LayoutLoader instance;
	private Context mContext;

	private LayoutLoader(Context context)
	{
		this.mContext = context;
	}

	public static LayoutLoader getInstance(Context context)
	{
		if (instance == null)
		{
			instance = new LayoutLoader(context);
		}
		return instance;
	}

	public int getLayoutID(String resIDName) throws NameNotFoundException,
			ClassNotFoundException, IllegalArgumentException,
			IllegalAccessException
	{
		int resID = readResID("layout", resIDName);
		if (resID == 0)
		{
			
		}
		return resID;
	}

	public int readResID(String type, String resIDName)
			throws NameNotFoundException, ClassNotFoundException,
			IllegalArgumentException, IllegalAccessException
	{
		String packageName;
		PackageManager pm = mContext.getPackageManager();
		PackageInfo pi = pm.getPackageInfo(mContext.getPackageName(), 0);
		packageName = pi.packageName;
		if (packageName == null || packageName.equalsIgnoreCase(""))
		{
			throw new NameNotFoundException("没有发现类");
		}
		packageName = packageName + ".R";
		Class<?> clazz = Class.forName(packageName);
		Class<?> cls = readResClass(clazz, packageName + "$" + type);
		if (cls == null)
		{
			throw new NameNotFoundException("没有发现类");
		}
		return readResID(cls, resIDName);

	}

	public Class<?> readResClass(Class<?> cls, String respackageName)
	{
		Class<?>[] classes = cls.getDeclaredClasses();
		for (int i = 0; i < classes.length; i++)
		{
			Class<?> tempClass = classes[i];
			Log.v("TAReadSystemRes", tempClass.getName());
			if (tempClass.getName().equalsIgnoreCase(respackageName))
			{
				return tempClass;
			}
		}
		return null;
	}

	public int readResID(Class<?> cls, String resIDName)
			throws IllegalArgumentException, IllegalAccessException
	{

		Field[] fields = cls.getDeclaredFields();
		for (int j = 0; j < fields.length; j++)
		{
			if (fields[j].getName().equalsIgnoreCase(resIDName))
			{
				return fields[j].getInt(cls);
			}
		}
		return 0;
	}

}

十、MainActivity.java

package com.jltxgcy.iocdemo;

import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

import com.jltxgcy.framework.BaseActivity;
import com.jltxgcy.framework.annotation.InjectResource;
import com.jltxgcy.framework.annotation.InjectView;

public class MainActivity extends BaseActivity {
	@InjectResource(id=R.string.app_name)
    String appNameString;
	@InjectView(id=R.id.tv_display)
	TextView tView;
	@InjectView(id=R.id.btn_imagecache)
	Button btnImagecache;
	@InjectView(id=R.id.btn_http)
	Button btnHttp;

	@Override
	protected void onAfterOnCreate(Bundle savedInstanceState)
	{
		tView.setText(appNameString);
		super.onAfterOnCreate(savedInstanceState);
		
	}
	
	@Override
	protected void onAfterSetContentView()
	{
		// TODO Auto-generated method stub
		super.onAfterSetContentView();
		OnClickListener onClickListener = new OnClickListener()
		{

			@Override
			public void onClick(View v)
			{
				// TODO Auto-generated method stub
				switch (v.getId())
				{
				case R.id.btn_imagecache:
					tView.setText("图片缓存模块");
					break;
				case R.id.btn_http:
					tView.setText("http模块");
					break;
				default:
					break;
				}
			}
		};
		btnImagecache.setOnClickListener(onClickListener);
		btnHttp.setOnClickListener(onClickListener);
	}

}

十一、main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
	android:orientation="vertical"
    tools:context=".MainActivity" >
 
    <TextView
        android:id="@+id/tv_display"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />
       <Button
        android:id="@+id/btn_imagecache"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="图片缓存模块" />
       <Button
        android:id="@+id/btn_http"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="HTTP模块" />

</LinearLayout>

十二、解释

           field.isAnnotationPresent(InjectView.class),判断该字段上是否有注解。如果有可以取得注解的内容。注解是动态解析的。

           @Override 

           @Deprecated 

           @SuppressWarnings 这些都是注解

            1、定义注解

package com.jltxgcy.framework.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(
{ ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
public @interface InjectResource
{
	int id() default -1;
}

            2、使用注解(@的方式)

@InjectResource(id=R.string.app_name)
    String appNameString;
           3、在程序中动态注入。Inject。

private void injectResource(Activity activity, Field field)
	{
		// TODO Auto-generated method stub
		if (field.isAnnotationPresent(InjectResource.class))
		{
			InjectResource resourceJect = field
					.getAnnotation(InjectResource.class);
			int resourceID = resourceJect.id();
			try
			{
				field.setAccessible(true);
				Resources resources = activity.getResources();
				String type = resources.getResourceTypeName(resourceID);
				if (type.equalsIgnoreCase("string"))
				{
					field.set(activity,
							activity.getResources().getString(resourceID));
				} else if (type.equalsIgnoreCase("drawable"))
				{
					field.set(activity,
							activity.getResources().getDrawable(resourceID));
				} else if (type.equalsIgnoreCase("layout"))
				{
					field.set(activity,
							activity.getResources().getLayout(resourceID));
				} else if (type.equalsIgnoreCase("array"))
				{
					if (field.getType().equals(int[].class))
					{
						field.set(activity, activity.getResources()
								.getIntArray(resourceID));
					} else if (field.getType().equals(String[].class))
					{
						field.set(activity, activity.getResources()
								.getStringArray(resourceID));
					} else
					{
						field.set(activity, activity.getResources()
								.getStringArray(resourceID));
					}

				} else if (type.equalsIgnoreCase("color"))
				{
					if (field.getType().equals(Integer.TYPE))
					{
						field.set(activity,
								activity.getResources().getColor(resourceID));
					} else
					{
						field.set(activity, activity.getResources()
								.getColorStateList(resourceID));
					}

				}
			} catch (Exception e)
			{
				e.printStackTrace();
			}
		}
	}

            代码地址:https://github.com/jltxgcy/Demo

你可能感兴趣的:(Android IOC模块,利用了Java反射和Java注解)