Saturday, August 29, 2015

[AndroidAnnotations_EnhancedComponent] - @EActivity

1. @EActivity Basic

1.1 Android

@EActivity의 사용은 안드로이드 Activity 클래스를 만들 때 사용하게 된다. 가장 기본적으로 사용되는 Annotation이라고 볼 수 있다. @EActivity annotation은 반드시 layout id가 필요하며, 해당 값은 activity 의 ContentView로 연결된다. 따라서 이것을 Framework를 사용하지 않고 안드로이드 코드로 작성한다면 아래와 같은 코드가 작성된다.

import android.app.Activity;
import android.os.Bundle;

public class MainActivity extends Activity{

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

1.2 AndroidAnnotations

반면에 이를 AA Framework를 이용하게 되면 아래와 같이 코드가 간결해짐을 알 수 있다.

import android.app.Activity;
import org.androidannotations.annotations.Click;
import org.androidannotations.annotations.EActivity;

@EActivity(R.layout.activity_main)
public class AAMainActivity extends Activity{
}

2. Intent Activity

2.1 Android

Android 에서 기본적으로 Activity간에 이동을 하는 경우에 intent를 사용하게 되는데, Intent의 연결도 한결 간결하게 표현됨을 알 수 있다. 먼저 Intent 객체를 생성하여 해당 클래스에 대한 intent 객체를 생헝하고 startActivity를 이용하여 해당 intent를 실행하는 구조로 작동된다. 따라서 기존 Android 소스 코드는 다음과 같이 표현된다.

Intent intent = new Intent(MainActivity.this, LoginActivity.class);
startActivity(intent);

2.2 AndroidAnnotations

해당 Framework를 사용하여 Activity를 @EActivity를 이용하여 클래스 파일을 생성할 경우에는 LoginActvity_.class로 클래스가 생성되고 따라서 intent를 호출하는 문법은 아래와 같이 변경되게 된다.

Intent intent = AALoginActivity_.intent(AAMainActivity.this).get();
startActivity(intent);

또한 해당 문법은 아래와 같이 표현될 수 있다.

AALoginActivity_.intent(getApplicationContext()).flags(Intent.FLAG_ACTIVITY_NEW_TASK).start();

Wednesday, August 26, 2015

[What is java annotation 03] - Creating your Own Annotations?

3. Creating your Own Annotations

3.1. Annotation 선언 방법

Custom Annotation을 만들기 위해서는 class 또는 interface로 아래와 같이 코드가 구현되어야 합니다.

public @interface Man {
    boolean isMan() default true;
    int age();
    String name();
    String[] have();
}

위와 같이 Annotation을 선언한 뒤 아래와 같이 해당 값들을 입력해야 Annotation 사용이 가능합니다. "Default" value를 지정할 경우에는 따로 값을 지정하지 않아도 사용 가능합니다.

@Man( age = 99, name = "Francis Kim", have = { "cellphone", "watch" })
public class MyAnnotationUse {
    ...
}

3.2. Annotation 용도 지정방법

아래와 같이 @Retention Annotation을 추가하면 해당 Annotation에 대한 용도 지정이 가능합니다.

@Retention(RetentionPolicy.RUNTIME)
public @interface Man {
    ...
}

3가지의 종류가 있다.

  • SOURCE : 컴파일러가 사용하고 클래스 파일 안에 포함되지 않는 경우
  • CLASS : 컴파일시 클래스 파일 안에 포함되나 VM에서 무시하는 경우
  • RUNTIME : 컴파일시 포함되고 VM에서 인식 하는 경우가 있다

3.2. Annotation 범위 지정방법

ElementType에 8가지 범위가 선언이 가능하며, 선언되지 않은 범위에 대해 Annotation을 사용할 경우 해당 Annotation은 무시됩니다. 또한 타겟은 여러개 지정이 가능합니다.

@Target({ElementType.TYPE, ElementType.FIELD})
public @interface Man{
 ...
}
  • TYPE : 클래스, 인터페이스, Annotation, 또는 열거형 타입
  • FIELD : 필드 또는 열거형 타입의 값
  • METHOD : 메소드
  • PARAMETER : 메소드의 인자
  • CONSTRUCTOR : 클래스 생성자
  • LOCAL_VARIABLE : 메소드 내부 변수
  • ANNOTATION_TYPE : Annotation 타입
  • PACKAGE : 패키지

참고 논문 및 사이트

1. Java Annotation: 인터페이스 강요로부터 자유를… - http://www.nextree.co.kr/p5864/

2. Java Annotations - http://tutorials.jenkov.com/java/annotations.html

3. Annotation과 Reflection, 그리고 코드 속의 MetaData - http://kang594.blog.me/39704853

[What is java annotation 02] - Annotation Basics?

2. Annotation Basics

Java annotation은 다음과 같이 표현됩니다.

@Deprecated, @Override, @SuppressWarings

위 3가지 Annotation의 경우에 Compiler instructions으로 이미 Java에서 제공되는 것 입니다.

2.1. @Deprecated

Class, Method, Field에 해당 annotation을 표시해두면 해당되는 것들은 사용하지 마라 라고 권고하는 것 입니다. 해당 annotation은 compile시에 warning(경고)를 표시해줍니다.

@Deprecated
public class DeprecatedClass {

    public DeprecatedClass() {
    }

    @Deprecated
    public static final String deprecatedStr = "Deprecated"

    @Deprecated
    public void deprecatedMethod(){
    }

}
public class Main {

    public static void main(String[] args) {
        // Class Call
        DeprecatedClass deprecatedClass = new DeprecatedClass();
        // Method Call
        deprecatedClass.deprecatedMethod();
        // Field Call
        String str = DeprecatedClass.deprecatedStr;
    }
}

2.2. @Override

@Override annotation는 superclass(부모 클래스)에 대해 상속 받아 override 할 경우에 사용됩니다. 만약 superclass에 해당 method가 없다면, compile시 error를 발생시킵니다.

public class ParentClass {

    public void extendMethod(){

    }

}
package com.example.annotation;

public class ChildClass extends  ParentClass{

    @Override
    public void extendMethod() {
        super.extendMethod();
    }

    @Override
    public void notExtendMethod(){

    }

}

2.3 @SuppressWarnings

@SuppressWarning 는 warning을 발생하는 것들에 대하여 warning을 제거하는 용도로 사용됩니다. Deprecated된 명령어를 사용하거나, 보장되지 않는 형변환을 할 때 등 컴파일 시점에 warning을 발생하는 경우에 대해서 warning을 제거할 수 있도록 합니다.

@SuppressWarnings("deprecation")
public class SuppressWarningsClass {

    public void method(){
        DeprecatedClass deprecatedClass = new DeprecatedClass();
    }

}

참고 논문 및 사이트

1. Java Annotation: 인터페이스 강요로부터 자유를… - http://www.nextree.co.kr/p5864/

2. Java Annotations - http://tutorials.jenkov.com/java/annotations.html

[What is java annotation 01] - Annotation?

1. Annotation ?

Annotation의 '주석' 이라는 의미를 가진 단어입니다. 하지만 Java 언어에서는 우리가 흔히 알고있는 일반적인 주석 '//' , '/**/' 과는 다른 용도로 사용됩니다. Annotation은 구현되는 정보에 따라 연결되는 방향이 결정되며, 전체 소스코드에서 비즈니스 로직에 영향을 주지는 않지만 해당 타겟의 연결 방법이나 소스 코드의 구조를 변경할 수 있는 역할을 합니다.

Java 어노테이션은 3가지 기능을 수행할 수 있습니다.

  • Compile instructions (컴파일시)
  • Build-time instructions (빌드시)
  • Runtime instructions (실행시)

Build Time에 Java annotations을 쓴다면, Build Process에서 Source Code 생성, Source Code 컴파일, XML 파일들 생성, Compile Code 패키징, jar 파일에 넣는 작업을 모두 수행하게 됩니다. 보통 Apache Ant, Apace Maven을 사용하며, Build Tool이 위의 작업을 수행하게 됩니다.

자바 Annotation은 컴파일 이후에는 판단 할 수 없지만, Runtime 시에도 Annotation을 사용할 수 있습니다. Runtime시에 작동되는 Annotation은 Java Refelection()에 접근가능하며 명령이나 third party api를 호출할 수 있습니다.

1.1. Java Reflection

Class 정보를 읽어 Instance에 Annotation에 해당하는 기능을 정의하는 방식으로 Web Framework에서 많이 사용되는 Spring Framework가 주로 사용 하는 방식이다. Android 계열에서는 DaggerRoboGuice와 같은 프레임워크가 해당되는 Annotation 사용방법을 사용하고 있다.

1.2. Annotation Processing Tool (apt)

Compile 단계에서 Annotation 이 정의된 타겟의 정보를 미리 정의 하는 방식으로 AndroidAnnotations Framework가 해당되는 기능을 수행한다. Source Code 에서 Annotation을 지정한다면, Annotation Proceesor가 해당되는 내용에 대한 소스코드를 생성하고 그 파일을 다시 생성하는 방식을 말합니다. 이와 같이 Compile 단계에서 수행하기 때문에 Runtime 시에는 영향이 거의 없다는 장점이 있습니다.

참고 논문 및 사이트

1. Java Annotation: 인터페이스 강요로부터 자유를… - http://www.nextree.co.kr/p5864/

2. Java Annotations - 인터페이스 강요로부터 자유를… - http://tutorials.jenkov.com/java/annotations.html

3. Android 와 Annotation - http://tosslab.github.io/android/2015/03/01/02.android%20%EC%99%80%20annotation/

Monday, August 24, 2015

AndroidAnnotations Intellij(or Android Studio 1.3) Setting

First

  • Create Android Gradle Empty Project

Second

  • Set build.gradle ( Top-level build File )
buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        // replace with the current version of the Android plugin
        classpath 'com.android.tools.build:gradle:1.2.3'
        // the latest version of the android-apt plugin
        classpath 'com.neenbedankt.gradle.plugins:android-apt:1.4'
    }
}

repositories {
    mavenCentral()
    mavenLocal()
}
  • Set build.gradle ( Application build file )
buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        // replace with the current version of the Android plugin
        classpath 'com.android.tools.build:gradle:1.2.3'
        // the latest version of the android-apt plugin
        classpath 'com.neenbedankt.gradle.plugins:android-apt:1.4'
    }
}

repositories {
    mavenCentral()
    mavenLocal()
}

apply plugin: 'com.android.application'
apply plugin: 'com.neenbedankt.android-apt'
def AAVersion = '3.3.2' // change this to your desired version, for example the latest stable: 3.3.2

dependencies {
    apt "org.androidannotations:androidannotations:$AAVersion"
    compile "org.androidannotations:androidannotations-api:$AAVersion"
}

apt {
    arguments {
        androidManifestFile variant.outputs[0].processResources.manifestFile
        // if you have multiple outputs (when using splits), you may want to have other index than 0

        // If you're using flavors you should use the following line instead of hard-coded packageName
        resourcePackageName "com.juranoaa.sample01"

        // You can set optional annotation processing options here, like these commented options:
        logLevel 'INFO'
        logFile '/var/log/aa.log'
    }
}

android {
    compileSdkVersion 22
    buildToolsVersion "22.0.1"

    defaultConfig {
        applicationId "com.juranoaa.sample01"
        minSdkVersion 21
        targetSdkVersion 22
        versionCode 1
        versionName "1.0"
    }
}

Third

  • Set Annotatioin processors
[ File -> Other Settings -> Default Settings... -> Build, Execution, Deployment -> Compiler -> Annotation Processor ]
Checked Enable annotation processing

Fourth

  • Make java class and modify xml file.
package com.juranoaa.sample01;

import android.app.Activity;
import android.widget.EditText;
import android.widget.TextView;
import org.androidannotations.annotations.Click;
import org.androidannotations.annotations.EActivity;
import org.androidannotations.annotations.ViewById;

@EActivity(R.layout.activity_main)
public class AAMainActivity extends Activity {

    @ViewById(R.id.myInput)
    EditText myInput;

    @ViewById(R.id.myTextView)
    TextView textView;

    @Click(R.id.myButton)
    void myButton() {
        String name = myInput.getText().toString();
        textView.setText("Hello " + name);
    }
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="fill_parent"
              android:layout_height="fill_parent">

    <EditText
            android:id="@+id/myInput"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            />
    <Button
            android:id="@+id/myButton"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="Click me!"
            />
    <TextView
            android:id="@+id/myTextView"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            />

</LinearLayout>

Problem?

P: Not find my class ( ...MyActivity_ )
S: Clean project [ Build -> Clean Project ]

+ Add Screen shot

File -> Other Settings -> Default Settings... -> Build, Execution, Deployment -> Compiler -> Annotation Processor
image

Checked Enabled annotation processing

image