標籤:
1 package com.example.ele_me.util; 2 3 import java.lang.annotation.Annotation; 4 import java.lang.reflect.Field; 5 6 import android.app.Activity; 7 8 /** 9 * Very lightweight form of injection, inspired by RoboGuice, for injecting common ui elements.10 * <p>11 * Usage is very simple. In your Activity, define some fields as follows:12 *13 * <pre class="code">14 * @InjectView(R.id.fetch_button)15 * private Button mFetchButton;16 * @InjectView(R.id.submit_button)17 * private Button mSubmitButton;18 * @InjectView(R.id.main_view)19 * private TextView mTextView;20 * </pre>21 * <p>22 * Then, inside your Activity‘s onCreate() method, perform the injection like this:23 *24 * <pre class="code">25 * setContentView(R.layout.main_layout);26 * Injector.get(this).inject();27 * </pre>28 * <p>29 * See the {@link #inject()} method for full details of how it works. Note that the fields are30 * fetched and assigned at the time you call {@link #inject()}, consequently you should not do this31 * until after you‘ve called the setContentView() method.32 */33 public final class Injector {34 private final Activity mActivity;35 36 private Injector(Activity activity) {37 mActivity = activity;38 }39 //mActicity本身擁有獨立的變量,並賦值給class Injector,然而我們也可透過修改activity去改變mActivity。40 /**41 * Gets an {@link Injector} capable of injecting fields for the given Activity.42 */43 public static Injector get(Activity activity) {44 return new Injector(activity);45 }46 47 /**48 * Injects all fields that are marked with the {@link InjectView} annotation.49 * <p>50 * For each field marked with the InjectView annotation, a call to51 * {@link Activity#findViewById(int)} will be made, passing in the resource id stored in the52 * value() method of the InjectView annotation as the int parameter, and the result of this call53 * will be assigned to the field.54 *55 * @throws IllegalStateException if injection fails, common causes being that you have used an56 * invalid id value, or you haven‘t called setContentView() on your Activity.57 */58 public void inject()59 //inject等待被另一個Java檔召喚。60 {61 for (Field field : mActivity.getClass().getDeclaredFields()) 62 //Field是一個對象類型,其作用等同於findViewById一樣,在於捕捉其對象。而下面的for迴圈則為了去捕捉對象所需要運用到的算式。63 {64 for (Annotation annotation : field.getAnnotations()) {65 if (annotation.annotationType().equals(InjectView.class)) {66 try {67 Class<?> fieldType = field.getType();68 int idValue = InjectView.class.cast(annotation).value();69 field.setAccessible(true);70 Object injectedValue = fieldType.cast(mActivity.findViewById(idValue));71 if (injectedValue == null) {72 throw new IllegalStateException("findViewById(" + idValue73 + ") gave null for " +74 field + ", can‘t inject");75 }76 field.set(mActivity, injectedValue);77 field.setAccessible(false);78 } catch (IllegalAccessException e) {79 throw new IllegalStateException(e);80 }81 }82 }83 }84 }85 }
這是一個必須複製的編碼。我們必須重新開一個Java檔案去讓injectView運行,injectView本身並不會獨自地去尋找對象,而是透過injectView Inject()去運算,並且尋找對象。
安卓中級教程(2):@InjectView中的對象inject