PyxInjector 1.1.1 Update

PyxInjector 1.1.1 Update

Github: WindSekirun/PyxInjector

English

  • Remove explicit keyword ‘resource =’ when paramter is one
  • Add ‘InvalidAnnotationException‘ when mtehod woth annotation field have invalid form.
  • Implement new annotation field: OnSeekBarChange, OnEditTextChange, OnCheckChange
  • Implement Non-Activity / Fragment binding feature
  • Update sample project follew up with library project.

Korean

  • 파라미터가 1개일 경우 resource = 선언 제거
  • 메서드에 부착된 어노테이션 필드가 부적합할 때 InvalidAnnotationException 를 보냅니다.
  • OnSeekBarChange, OnEditTextChange, OnCheckChange 가 추가되었습니다.
  • 액티비티, 프래그먼트가 아닌 곳에서 바인딩을 실행할 수 있도록 추가하였습니다. 예) RecyclerView.ViewHolder
  • 샘플 앱 업데이트

PyxInjector :: Dependency Injections Library with easy way

안드로이드 개발자라면 거의 대부분 ButterKnife 를 한번 이상은 사용했을 텐데, ButterKnife의 주요 기능은 어노테이션을 사용하여 필드 또는 메서드에 기능을 부착하는 것이다.

가령 예를 들면, @BindView(R.id.title) TextView title; 으로 findViewById를 쓰지 않고 뷰를 찾을 수 있게 해준다.

다만 최근 들어서는 조금 기피하고 있었는데.. 아래 이와 같다.

  1. 주로 개인용 앱을 개발할 때에는 Kotlin 을 사용하니까 Kotlin Android Extension 을 통해서 findViewById 등을 전혀 쓸 필요가 없고, 굳이 자바로 개발(..) 해야 될 때에만 ButterKnife를 사용했었다.
  2. annotationProcessor 로 인한 빌드 타임 증가
  3. 필드 이름과 리소스 id 이름을 같게 만드는 일이 다반수인데도 여전히 값을 적어야 함

이를 해결하기 위해 10월 27일 오후 6시쯤 떠올려 어느정도 제작한 라이브러리가 이 PyxInjector 이다.

PyxInjector 소개

Github: https://github.com/WindSekirun/PyxInjector

Pyx 는 남쪽 하늘에 있는 작고 희미한 별자리인 Pyxis 의 약자이다.

아무리 눈에 띄지 않아도 그 기능을 수행한다는 의미에서 작명했다. 사실상 지을 이름이 없었다.

주요 주안점은 아래와 같다.

  1. @BindView, @OnClick 등 ButterKnife 에 있는 기능들의 구현
  2. 라이브러리 전 파트를 Kotlin으로 작성
  3. 암시적으로 값을 설정할 수 있게 대응함
  4. @Extra, @Argument 등으로 인텐트, 프래그먼트 Argument 등을 자동으로 받아옴
  5. Config 를 통하여 어떤 환경에서 암시적으로 잘 작동하도록 설정함

첫 릴리즈 (1.0.0) 기준으로 구현된 어노테이션은 아래와 같다.

  1. @BindView – 리소스 ID로 뷰 캐스팅
  2. @Extra – 인텐트 엑스트라를 가져옴
  3. @Argument – 프래그먼트 Argument를 가져옴
  4. @OnClick – 주어진 리소스 id에 해당하는 뷰를 클릭시 실행
  5. @OnClicks – OnClick의 리스트 버전
  6. @OnLongClick – 주어진 리소스 id에 해당하는 뷰를 길게 클릭시 실행
  7. @OnLongClicks – OnLongClick 의 리스트 버전

각 어노테이션의 설명과 예제는 README 에 있으니 여기에선 굳이 설명을 하지 않는다.

Before & After

적용하기 전

public class MainActivity extends AppCompatActivity {
    private TextView mTxtName;
    private TextView txtName2;
    private TextView txtName3;
    private Button btnDo;
    private Button btnDo2;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        TextView mTxtName = findViewById(R.id.txtName);
        TextView txtName2 = findViewById(R.id.txtName2);
        TextView txtName3 = findViewById(R.id.txtName3);
        Button btnDo = findViewById(R.id.btnDo);
        Button btnDo2 = findViewById(R.id.btnDo2);

        mTxtName.setText("resource id != field name with BindViewPrefix.PREFIX_M");
        txtName2.setText("resource id == field name");
        txtName3.setText("explicit statement");

        btnDo.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                clickDo(view);
            }
        });  
        
        btnDo2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                clickDo(view);
            }
        });
    }

    private void clickDo(View v) {
        Intent intent = new Intent(this, SecondActivity.class);
        intent.putExtra("name", "John");
        intent.putExtra("age", "17");
        startActivity(intent);
    }
}

적용한 후

public class MainActivity extends InjectActivity {
    private @BindView TextView mTxtName;
    private @BindView TextView txtName2;
    private @BindView(R.id.txtName3) TextView txtName3;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mTxtName.setText("resource id != field name with BindViewPrefix.PREFIX_M");
        txtName2.setText("resource id == field name");
        txtName3.setText("explicit statement");
    }

    @OnClicks({R.id.btnDo, R.id.btnDo2})
    private void clickDo(View v) {
        Intent intent = new Intent(this, SecondActivity.class);
        intent.putExtra("name", "John");
        intent.putExtra("age", "17");
        startActivity(intent);
    }
}

마무리

오랜만에 매우 재밌는 코딩을 한 것 같은 기분이다.

jitpack 에 배포했고, 차후 추가되는 Annotation 들은 그때그때 릴리즈 노트로 올릴 생각이다.