部分内容来自于 : http://www.tuicool.com/articles/feqmQj
我把注解,findViewById()的功能加进去了,当然还有待完善
BaseApplication类源码如下:
import java.util.ArrayList;import android.app.Activity;import android.app.Application;/**
* 功能描述:用于存放全局变量和公用的资源等
* @author android_ls
*/public class BaseApplication extends Application {
public static Context getContext(){
return AppManager.getAppManager().currentActivity().getApplicationContext();
}
/**
* 退出应用程序的时候,手动调用
*/
@Override
public void onTerminate() {
for (BaseActivity activity : activitys) {
activity.defaultFinish();
}
}
/**
* 获取App安装包信息
* @return
*/
public PackageInfo getPackageInfo() {
PackageInfo info = null;
try {
info = getPackageManager().getPackageInfo(getPackageName(), 0);
} catch (NameNotFoundException e) {
e.printStackTrace(System.err);
}
if(info == null) info = new PackageInfo();
return info;
}
}
BaseActivity类源码如下:
package com.lbt.hairdesigner;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.Window;
import android.widget.Toast;
import com.lbt.hairdesigner.utils.LogUtil;
/**
* 功能描述:对Activity类进行扩展
* @author android_ls
*/public abstract class BaseActivity extends Activity {
/**
* LOG打印标签
*/
private static final String TAG = BaseActivity.class.getSimpleName();
/**
* 全局的Context {@link #mContext = this.getApplicationContext();}
*/
protected Context mContext;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
int layoutId = getLayoutId();
if (layoutId != 0) {
setContentView(layoutId);
//调用注解,反射类的成员变量,布局控件就不用调用findViewById()方法了
// 书写方式: @InjectView(R.id.tv_pay_channel_value)
// private TextView tv_pay_channel_value;
Injector.get(this).inject();
// 删除窗口背景
getWindow().setBackgroundDrawable(null);
}
mContext = this.getApplicationContext();
((BaseApplication) this.getApplication()).addActivity(this);
// 向用户展示信息前的准备工作在这个方法里处理
preliminary();
}
/**
* 向用户展示信息前的准备工作在这个方法里处理
*/
protected void preliminary() {
setupViews(); // 初始化组件
initialized(); // 初始化数据
}
/**
* 获取全局的Context
* @return {@link #mContext = this.getApplicationContext();}
*/
public Context getContext() {
return mContext;
}
/**
* 布局文件ID
* @return
*/
protected abstract int getLayoutId();
/**
* 初始化组件
*/
protected abstract void setupViews();
/**
* 初始化数据
*/
protected abstract void initialized();
/**
* 通过Class跳转界面
**/
public void startActivity(Class<?> cls) {
startActivity(cls, null);
}
/**
* 含有Bundle通过Class跳转界面
**/
public void startActivity(Class<?> cls, Bundle bundle) {
Intent intent = new Intent();
intent.setClass(this, cls);
if (bundle != null) {
intent.putExtras(bundle);
}
startActivity(intent);
//这里有2个动画的配置文件
overridePendingTransition(R.anim.push_left_in, R.anim.push_left_out);
}
/**
* 通过Action跳转界面
**/
public void startActivity(String action) {
startActivity(action, null);
}
/**
* 含有Bundle通过Action跳转界面
**/
public void startActivity(String action, Bundle bundle) {
Intent intent = new Intent();
intent.setAction(action);
if (bundle != null) {
intent.putExtras(bundle);
}
startActivity(intent);
overridePendingTransition(R.anim.push_left_in, R.anim.push_left_out);
}
/**
* 含有Bundle通过Class打开编辑界面
**/
public void startActivityForResult(Class<?> cls, Bundle bundle, int requestCode) {
Intent intent = new Intent();
intent.setClass(this, cls);
if (bundle != null) {
intent.putExtras(bundle);
}
startActivityForResult(intent, requestCode);
overridePendingTransition(R.anim.push_left_in, R.anim.push_left_out);
}
/**
* 带有右进右出动画的退出
*/
@Override
public void finish() {
super.finish();
overridePendingTransition(R.anim.push_right_in, R.anim.push_right_out);
}
/**
* 默认退出
*/
public void defaultFinish() {
super.finish();
}
}
然后是注解
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Use this annotation to mark the fields of your Activity as being injectable.
* <p>
* See the {@link Injector} class for more details of how this operates.
*/
@Target({ ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
public @interface InjectView {
/**
* The resource id of the View to find and inject.
*/
public int value();
}
然后是注解的反射
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import android.app.Activity;
/**
* Very lightweight form of injection, inspired by RoboGuice, for injecting common ui elements.
* <p>
* Usage is very simple. In your Activity, define some fields as follows:
*
* <pre class="code">
* @InjectView(R.id.fetch_button)
* private Button mFetchButton;
* @InjectView(R.id.submit_button)
* private Button mSubmitButton;
* @InjectView(R.id.main_view)
* private TextView mTextView;
* </pre>
* <p>
* Then, inside your Activity's onCreate() method, perform the injection like this:
*
* <pre class="code">
* setContentView(R.layout.main_layout);
* Injector.get(this).inject();
* </pre>
* <p>
* See the {@link #inject()} method for full details of how it works. Note that the fields are
* fetched and assigned at the time you call {@link #inject()}, consequently you should not do this
* until after you've called the setContentView() method.
*/
public final class Injector {
private final Activity mActivity;
private Injector(Activity activity) {
mActivity = activity;
}
/**
* Gets an {@link Injector} capable of injecting fields for the given Activity.
*/
public static Injector get(Activity activity) {
return new Injector(activity);
}
/**
* Injects all fields that are marked with the {@link InjectView} annotation.
* <p>
* For each field marked with the InjectView annotation, a call to
* {@link Activity#findViewById(int)} will be made, passing in the resource id stored in the
* value() method of the InjectView annotation as the int parameter, and the result of this call
* will be assigned to the field.
*
* @throws IllegalStateException if injection fails, common causes being that you have used an
* invalid id value, or you haven't called setContentView() on your Activity.
*/
public void inject() {
for (Field field : mActivity.getClass().getDeclaredFields()) {
for (Annotation annotation : field.getAnnotations()) {
if (annotation.annotationType().equals(InjectView.class)) {
try {
Class<?> fieldType = field.getType();
int idValue = InjectView.class.cast(annotation).value();
field.setAccessible(true);
Object injectedValue = fieldType.cast(mActivity.findViewById(idValue));
if (injectedValue == null) {
throw new IllegalStateException("findViewById(" + idValue
+ ") gave null for " +
field + ", can't inject");
}
field.set(mActivity, injectedValue);
field.setAccessible(false);
} catch (IllegalAccessException e) {
throw new IllegalStateException(e);
}
}
}
}
}
}