Android IOC模塊,利用瞭Java反射和Java註解

一、整體工程圖

 

二、BaseActivity.java

[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

[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

[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

[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

[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

[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

[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

[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

[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

[java]  

<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、定義註解

[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;  

}  

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

[java]  

@InjectResource(id=R.string.app_name)  

    String appNameString;  

           3、在程序中動態註入。Inject。

[java 

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();  

            }  

        }  

    }  

 

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *