출처 : http://blog.softwaregeeks.org/archives/616

리플렉션(Reflection)을 활용한 안드로이드 위젯 매핑(Mapping) 간소화 하기

안드로이드 어플을 만들다보면 안드로이드 위젯(Widget)을 매핑하는 코드를 작성합니다.

위젯이 3~4개 정도면 쉽게 작성할 수 있지만 복잡한 액티비티(Activity)의 경우는 십여개가 넘는 위젯이 존재하고 아래와 같은 코드의 반복이 일어납니다.

자바의 리플렉션을 활용하면 아래의 코드를 간소화 할 수 있습니다.

1
2
3
4
EditText trackEditText = (EditText) findViewById(R.id.title);
EditText artistEditText = (EditText) findViewById(R.id.artist);
EditText albumEditText = (EditText) findViewById(R.id.album);
TextView pathTextView = (TextView) findViewById(R.id.path);



리플렉션을 활용하여 자바 객체의 필드를 모두 가져온 후 activity.getResources().getIdentifier(identifierString, “id”, activity.getPackageName()) 메소드를 활용하여 R.java 에 정의된 id 값을 추출 후 이 값으로 다시 findViewById 메소드로 View를 다시 조회하여 해당 객체를 필드에 값을 주입(Injection)하는 단계를 거칩니다.

이 방법의 전제는 위젯의 id 값과 필드의 이름이 일치한다는 규칙을 정한 것이여서 사용하려면 유의해야 합니다. 하단의 XML의 id값과 필드명을 유심히 살펴보세요~

src/org/softwaregeeks/needletagger/Editor.java

1
2
3
4
5
6
7
8
9
10
11
private EditText trackEditText;
private EditText artistEditText;
private EditText albumEditText;
private TextView pathTextView;
 
@Override
public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.editor);
  UIHelper.mappingViews(this);
}

res/layout/editor.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent">
  <EditText android:id="@+id/trackEditText"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content" />
  <EditText android:id="@+id/artistEditText"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content" />
  <EditText android:id="@+id/albumEditText"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content" />
  <TextView android:id="@+id/pathTextView"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content" />
</LinearLayout>



실제 리플렉션을 활용하여 매핑하는 메소드는 다음과 같습니다. 그럼 도움이 되셨길 바랍니다~ :D


org/softwaregeeks/framework/android/util/UIHelper.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
package org.softwaregeeks.framework.android.util;
 
import java.lang.reflect.Field;
 
import android.app.Activity;
import android.view.View;
import android.widget.TextView;
 
public class UIHelper
{
  public static void mappingViews(Object object)
  {
    if( !(object instanceof Activity) )
      return;
 
    Activity activity = (Activity)object;
    Field[] fields = activity.getClass().getDeclaredFields();
    for (Field field : fields)
    {
      String identifierString = field.getName();
      int identifier = activity.getResources().getIdentifier(identifierString, "id", activity.getPackageName());
      if( identifier == 0 )
        continue;
 
      View findedView = activity.findViewById(identifier);
      if( findedView == null )
        continue;
 
      if( findedView.getClass() == field.getType() ) {
        try
        {
          field.setAccessible(true);
              field.set(object, findedView);
        }
        catch (IllegalArgumentException e)
        {
          e.printStackTrace();
        }
        catch (IllegalAccessException e)
        {
          e.printStackTrace();
        }
      }
    }
  }
}

+ Recent posts