Activity間のデータ転送を列挙する

4801 ワード

通常、パラメータを携帯する必要がある場合は、activityから別のインタフェースにジャンプします.コードは次のとおりです.
 public static void startActivity(Activity activity,UserChange userChange){
        Intent intent = new Intent(activity,UserChangeActivity.class);
        intent.putExtra(DATA_KEY,userChange);
        activity.startActivity(intent);

    }

そしてジャンプしたactivityでデータを取得します
UserChange userChange;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
	userChange = (UserChange) getIntent().getSerializableExtra(DATA_KEY);
}

以前ARouterのソースコードを見たときを覚えています.ジャンプするactivityは、フィールドに注釈を付けるだけです.渡されたパラメータを自動的に解析できます.実現しても難しくないと思って、手動でやめました.
ジャンプの方法はカプセル化され,まず汎用的なkeyを定義した.ジャンプ時にパラメータを持つ方法をカプセル化しました.これでジャンプは簡単ですが、ジャンプするclassとデータを転送すればいいです.
	public final static String INTENT_DATA_KEY="INTENT_DATA_KEY";
	/**
     *  Activity
     *
     * @param clazz Activity 
     */
    protected void startActivity(Class clazz,Object data) {
        Bundle bundle = new Bundle();
        putData(bundle,INTENT_DATA_KEY,data);
        startActivityForResult(clazz, -1, bundle);

    }

	private void putData(Bundle bundle,String key,Object data){
        if (data instanceof Integer){
            bundle.putInt(key,(Integer) data);
        }else if (data instanceof String){
            bundle.putString(key,(String) data);
        }else if(data instanceof Serializable){
            bundle.putSerializable(key,(Serializable) data);
        }
	}

プロパティに列挙修飾を追加するだけで、受信場所は簡単です.
@IntentData
UserChange userChange;

もちろん、複数のパラメータの場合、属性の列挙に対応するkeyは、ここのmapのうちのkeyと1つずつ対応する
/**
 *  Activity
 *
 * @param clazz Activity 
 */
protected void startActivity(Class clazz,Map datas) {
    Bundle bundle = new Bundle();
    for (Map.Entry entry : datas.entrySet()) {
        putData(bundle,entry.getKey(),entry.getValue());
    }
    startActivityForResult(clazz, -1, bundle);

}

列挙、簡単です.
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface IntentData {
    String key() default INTENT_DATA_KEY;

}

それからonCreateの中で列挙するフィールドを見つけて、解析して、値を割り当てます
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    resolveIntentData();
  
}

属性を巡回して、IntentData列挙のある属性を見つけます
void resolveIntentData(){

 Field[] fields= getClass().getDeclaredFields();
 for (int i=0;i

1つずつ見つけて値を付ける.ここに罠がある.Serializable判断は必ず最後に置くべきで、他のタイプはSerializeableインタフェースを実現しているので、判断が一番前に置くと、いつも条件に合致します.
private void setIntentData(IntentData intentData,Field f){
    if (intentData!=null){
        Intent intent = getIntent();
        // 
        Class clazz=f.getType();
        Object o = null;
        String key = intentData.key();
		// 
        if (Integer.class==clazz||int.class==clazz){
            o = intent.getIntExtra(key,0);
        }else if (String.class==clazz){
            o = intent.getStringExtra(key);
        } else if (Boolean.class==clazz||boolean.class==clazz){
            o = intent.getBooleanExtra(key,false);
        }else if (Serializable.class.isAssignableFrom(clazz)){
            o = intent.getSerializableExtra(key);
        }
		// , 
        if (o!=null) {
            ReflectUtil.setField(this, f.getName(), o);
        }
    }
}

値を割り当てる操作は簡単です.もちろんButterKnifeのようにもできます.コンパイル期間中にコード処理を自動的に生成します.ただそれは難しいです.
public static Field getField(Class> clazz, String fieldName) {
    Field field = null;

    try {
        field = clazz.getDeclaredField(fieldName);
        field.setAccessible(true);
    } catch (NoSuchFieldException var4) {
        var4.printStackTrace();
    }

    return field;
}

public static void setField(Object obj, String fieldName, Object value) {
    Field field = getField(obj.getClass(), fieldName);
    if (field != null) {
        try {
            field.set(obj, value);
        } catch (IllegalAccessException var5) {
            var5.printStackTrace();
        }
    }

}

上記のコードをBaseActivityにカプセル化すると、後ジャンプインタフェース伝達パラメータが直接次のカプセル化方法を呼び出す.
	/**
     *  Activity
     *
     * @param clazz Activity 
     */
    protected void startActivity(Class clazz,Object data) {
        Bundle bundle = new Bundle();
        putData(bundle,INTENT_DATA_KEY,data);
        startActivityForResult(clazz, -1, bundle);

    }