'androidstudio'에 해당되는 글 3건

  1. 2014.12.02 AndroidStudio with Robolectric
  2. 2014.10.03 AndroidStudio Gradle + AspectJ
  3. 2013.11.08 Gradle + AndroidStudio + AndroidAnnotations with two different product flavor(diifferent packgename)
2014.12.02 19:41

손나 유용한 링크


https://github.com/codepath/android_guides/wiki/Robolectric-Installation-for-Unit-Testing#setting-up-for-android-studio


http://zerobrain.tistory.com/42



1. 플러그인을 붙였을때 3.8 Stub 에러가 날때?

iml 파일에서 Android Platform 엔트리를 제일 하단으로 위치하기


2. 이젠 테스트 클래스를 못찾는다면?

JUnit VM option 에다가 아래와 같이 클래스 패스를 추가한다.

저 길다란 부분은 대부분 에러났을때 콘솔 로그에 찍힌 부분에서 클래스 패스를 따오면 되고, 그 뒤에다가 추가로 테스트 클래스가 들어있는 패스를 추가해야 한다.(굵은 글씨)

하지만 맨처음부터 플래이 하지말고 일단 그래들 클린, 빌드를 해줘야 한다. 그래야 테스트 클래스가 컴파일되어 .class 파일이 위치할 패스가 보이기 때문


-classpath

 "/Applications/Android Studio.app/Contents/lib/idea_rt.jar:/Applications/Android Studio.app/Contents/plugins/junit/lib/junit-rt.jar:/Users/flask/Documents/workspace_android/RobolectricTest6/build/intermediates/classes/debug:/Users/flask/Documents/workspace_android/RobolectricTest6/lib/testrunner-1.1.jar:/Users/flask/.gradle/caches/modules-2/files-2.1/org.ow2.asm/asm/5.0.1/2fd56467a018aafe6ec6a73ccba520be4a7e1565/asm-5.0.1.jar:/Users/flask/.gradle/caches/modules-2/files-2.1/org.objenesis/objenesis/1.3/dc13ae4faca6df981fc7aeb5a522d9db446d5d50/objenesis-1.3.jar:/Users/flask/.gradle/caches/modules-2/files-2.1/com.google.guava/guava/14.0.1/69e12f4c6aeac392555f1ea86fab82b5e5e31ad4/guava-14.0.1.jar:/Users/flask/.gradle/caches/modules-2/files-2.1/com.squareup.dagger/dagger/1.1.0/49f2061c938987c8e56679a731d74fd8448d8742/dagger-1.1.0.jar:/Users/flask/.gradle/caches/modules-2/files-2.1/org.hamcrest/hamcrest-library/1.1/b988c01468e3398d46678a2eb48aeb5bde271e9f/hamcrest-library-1.1.jar:/Users/flask/.gradle/caches/modules-2/files-2.1/org.apache.ant/ant/1.8.0/7b456ca6b93900f96e58cc8371f03d90a9c1c8d1/ant-1.8.0.jar:/Users/flask/.gradle/caches/modules-2/files-2.1/com.squareup/fest-android/1.0.8/72b0763d5fd11a9ca769bb88367d92e43c0198e0/fest-android-1.0.8.jar:/Users/flask/Documents/workspace_android/RobolectricTest6/lib/testrunner-runtime-1.1.jar:/Users/flask/.gradle/caches/modules-2/files-2.1/com.almworks.sqlite4java/sqlite4java/0.282/745a7e2f35fdbe6336922e0d492c979dbbfa74fb/sqlite4java-0.282.jar:/Users/flask/.gradle/caches/modules-2/files-2.1/org.apache.maven/maven-ant-tasks/2.1.3/b09be554228d66d208e5fef5266844aacf443abc/maven-ant-tasks-2.1.3.jar:/Users/flask/.gradle/caches/modules-2/files-2.1/org.robolectric/robolectric-annotations/2.4/936c649cb0958d7fb5d3c09b31c56b3997f80650/robolectric-annotations-2.4.jar:/Users/flask/.gradle/caches/modules-2/files-2.1/commons-codec/commons-codec/1.3/fd32786786e2adb664d5ecc965da47629dca14ba/commons-codec-1.3.jar:/Users/flask/Documents/workspace_android/RobolectricTest6/lib/espresso-1.1.jar:/Users/flask/.gradle/caches/modules-2/files-2.1/org.robolectric/robolectric/2.4/5b3e395f0e422de3147d42918b7a5b08476f2377/robolectric-2.4.jar:/Users/flask/Documents/android-sdk/extras/android/m2repository/com/android/support/support-v4/19.1.0/support-v4-19.1.0.jar:/Users/flask/.gradle/caches/modules-2/files-2.1/org.ow2.asm/asm-commons/5.0.1/7b7147a390a93a14d2edfdcf3f7b0e87a0939c3e/asm-commons-5.0.1.jar:/Users/flask/.gradle/caches/modules-2/files-2.1/com.ximpleware/vtd-xml/2.11/ee5bcf62c1acf76434ee9f1c67a840bafef72a6d/vtd-xml-2.11.jar:/Users/flask/.gradle/caches/modules-2/files-2.1/org.ow2.asm/asm-tree/5.0.1/1b1e6e9d869acd704056d0a4223071a511c619e6/asm-tree-5.0.1.jar:/Users/flask/.gradle/caches/modules-2/files-2.1/junit/junit/4.11/4e031bb61df09069aeb2bffb4019e7a5034a4ee0/junit-4.11.jar:/Users/flask/.gradle/caches/modules-2/files-2.1/org.hamcrest/hamcrest-core/1.1/860340562250678d1a344907ac75754e259cdb14/hamcrest-core-1.1.jar:/Users/flask/.gradle/caches/modules-2/files-2.1/org.ow2.asm/asm-analysis/5.0.1/e286fbee48efacb4e7c175f7948d9d8b2ab52352/asm-analysis-5.0.1.jar:/Users/flask/.gradle/caches/modules-2/files-2.1/org.easytesting/fest-assert-core/2.0M10/cb7c91cf614901928ae405f19d9bcdedf82781db/fest-assert-core-2.0M10.jar:/Users/flask/.gradle/caches/modules-2/files-2.1/org.easytesting/fest-util/1.2.5/c4a8d7305b23b8d043be12c979813b096df11f44/fest-util-1.2.5.jar:/Users/flask/.gradle/caches/modules-2/files-2.1/org.apache.ant/ant-launcher/1.8.0/8b53ba16fa62fb1034da8f1de200ddc407c8381/ant-launcher-1.8.0.jar:/Users/flask/.gradle/caches/modules-2/files-2.1/javax.inject/javax.inject/1/6975da39a7040257bd51d21a231b76c915872d38/javax.inject-1.jar:/Users/flask/.gradle/caches/modules-2/files-2.1/org.ow2.asm/asm-util/5.0.1/7c8caddfbd0b2d7b844f8fcc75175b9cb9cf4724/asm-util-5.0.1.jar:/Users/flask/.gradle/caches/modules-2/files-2.1/org.hamcrest/hamcrest-integration/1.1/8d47177aa4da0f259fc823a39736bad2f09993d5/hamcrest-integration-1.1.jar:/Users/flask/Documents/android-sdk/platforms/android-19/android.jar:/Users/flask/Documents/android-sdk/platforms/android-19/data/res:/Users/flask/Documents/android-sdk/tools/support/annotations.jar:/Users/flask/Documents/workspace_android/RobolectricTest6/build/test-classes"



이렇게 추가하면,


프로젝트 디렉터리 안에 app/build/test-report/debug/classes/package.name.html


에 테스트 결과가 html 로 출력됨. 



3. 그런데 robolectric 에서 api 1 을 지원하지 않는다고 하면?



@Config(manifest = "./src/main/AndroidManifest.xml", emulateSdk = 18)

@RunWith(RobolectricTestRunner.class)

public class SimpleTest {


@Test

public void testSomething() throws Exception {

Activity activity = Robolectric.buildActivity(WebViewActivity.class).create().get();

assertTrue(activity != null);

}


@Test(expected = RuntimeException.class)

public void testShouldFail(){

throw new RuntimeException();

}

}



이게 테스트 클래스인데 .@Config 에 emulateSdk = 18 를 추가해주면됨(이상하게도 19 는 안된다...?)


이렇게 하면 플래이 버튼 눌러도 테스트가 돌아감!!




build.gradle



buildscript {

    repositories {

        mavenCentral()

    }


    dependencies {

        classpath 'com.android.tools.build:gradle:0.14.4'

        classpath 'org.robolectric:robolectric-gradle-plugin:0.13.+'

    }

}


allprojects {

    repositories {

        mavenCentral()

    }

}


apply plugin: 'android'

apply plugin: 'robolectric'


android {

    packagingOptions {

        exclude 'LICENSE.txt'

        exclude 'META-INF/LICENSE'

        exclude 'META-INF/LICENSE.txt'

        exclude 'META-INF/NOTICE'

    }

    compileSdkVersion 19

    buildToolsVersion "21.1.1"


    defaultConfig {

        minSdkVersion 18

        targetSdkVersion 18

        versionCode 2

        versionName "1.0.0-SNAPSHOT"

        testInstrumentationRunner "com.google.android.apps.common.testing.testrunner.GoogleInstrumentationTestRunner"

    }

    buildTypes {

        release {

            minifyEnabled false

        }

    }


    sourceSets {

        androidTest {

            setRoot('src/test')

        }

    }

}


robolectric {

    include '**/*Test.class'

    exclude '**/espresso/**/*.class'

}


dependencies {

    repositories {

        mavenCentral()

    }

    // Espresso

    androidTestCompile files('lib/espresso-1.1.jar', 'lib/testrunner-1.1.jar', 'lib/testrunner-runtime-1.1.jar')

    androidTestCompile 'com.google.guava:guava:14.0.1'

    androidTestCompile 'com.squareup.dagger:dagger:1.1.0'

    androidTestCompile 'org.hamcrest:hamcrest-integration:1.1'

    androidTestCompile 'org.hamcrest:hamcrest-core:1.1'

    androidTestCompile 'org.hamcrest:hamcrest-library:1.1'


    androidTestCompile('junit:junit:4.11') {

        exclude module: 'hamcrest-core'

    }

    androidTestCompile('org.robolectric:robolectric:2.4') {

        exclude module: 'classworlds'

        exclude module: 'commons-logging'

        exclude module: 'httpclient'

        exclude module: 'maven-artifact'

        exclude module: 'maven-artifact-manager'

        exclude module: 'maven-error-diagnostics'

        exclude module: 'maven-model'

        exclude module: 'maven-project'

        exclude module: 'maven-settings'

        exclude module: 'plexus-container-default'

        exclude module: 'plexus-interpolation'

        exclude module: 'plexus-utils'

        exclude module: 'wagon-file'

        exclude module: 'wagon-http-lightweight'

        exclude module: 'wagon-provider-api'

    }

    androidTestCompile 'com.squareup:fest-android:1.0.+'

}


apply plugin: 'idea'


idea {

    module {

        testOutputDir = file('build/test-classes/debug')

    }

}




처음에 할때 hemcrest 디팬던시가 없으면 classnotfound가 뜨니 잘 확인하고 추가해야함.
오류들도 html로 나오는데 꼭 확인해야함!






Robolectric 테스트 작성중 문제가 몇가지 있었는데

AndroidAnnotations 의 UiThread 어노테이션이 붙은 메소드가 실행이 안되는점(웃기게도 BackgroundThread 어노테이션이 붙은 메소드는 실행이 된다...)
이때는 

public void waitForUiThread() {
try {
// Fast forward to the end of the UI queue
Thread.sleep(500); // Work around a race condition where the UI thread doesn't yet have the task in its queue
Robolectric.runUiThreadTasksIncludingDelayedTasks();
} catch (InterruptedException e) {
e.printStackTrace();
}
}

이런식으로 ui thread 를 실행하라고 명시적으로 해줘야 한다. 아오 복잡해

그리고 리스트 뷰에서 아이템 클릭은

public void performClick(ListView lv, int position) {
lv.performItemClick(lv.getChildAt(position),
position,
lv.getAdapter().getItemId(position));
}

이런식으로 해주면되고,  인텐트가 실행이 됬는지 assertion  은


public <T> void assertIntent(Activity activity, Class<? extends T> klass) {
ShadowActivity shadowActivity = shadowOf(activity);
Intent startedIntent = shadowActivity.getNextStartedActivity();
ShadowIntent shadowIntent = shadowOf(startedIntent);
assertThat(shadowIntent.getComponent().getClassName(), equalTo(klass.getName()));
}

처럼 해주면된다.

이렇게 하다보니 AA에 너무 의존된게 많아져서 activity 에서 controller 로 기능을 뽑아냈는데 @EBean 으로 인젝션 받은 Service들은 어떻게 만들기 애매했다.(rest api를 호출해서 값을 가져와야하는거라서 네트워크 딜레이라던지, 로그인을 해야하고 세션처리, 등등을 해줘야 해서 개귀찮)
그래서 Mockito를 사용해서 각각 service 들을 모두 mock 으로 만들고 외부에서 넣어줬다.

androidTestCompile 'org.mockito:mockito-core:1.+'
androidTestCompile 'com.jayway.awaitility:awaitility:1.6.3'

그런데 afterViews 에서 서비스에 접근해 값을 패치를 하는데 이때는 컨트롤러도 mock해서 해주면 된다.
하지만 컨트롤러의 기본적인 기능들은 원래의 오리지널 메소드를 호출해야 하므로 mock() 이 아닌 spy()로 만들어 주면 된다. - 그런데 doc 에선 이렇게 하는 방법이 절대 제대로 하는게 아니다. 라고 하는듯. 






저작자 표시 비영리 변경 금지
신고
크리에이티브 커먼즈 라이선스
Creative Commons License
Trackback 0 Comment 0
2014.10.03 19:40

안드로이드 플젝을 하다가 반복되는 코드가 들어가야 할때가 있습니다.

예를들어 예외 처리시 다이얼로그를 띄워준다던가, 로그인 세션이 끊겼을때 다시 로그인을 시도하는등의 처리가 있는데, 로그인 세션이 끊겼을때의 경우, 


1. 서버로 리퀘스트 날림

2. 로그인 세션이 끊겨 리퀘스트가 실패(404 등등)

3. 예외를 잡고, 로그인을 시도

4-1. 성공시 다시 1 수행

4-2. 실패시 실패 다이얼로그 출력


이렇게 되는데 문제는 실패시 다시 해당 메소드를 호출해줘야 하는 문제가 있습니다.


그래서 처음 구현했을땐 각각의 리퀘스트를 날리는 메소드의 파라미터로 콜백을 줘서 처리를 했습니다.

그러다보니, 모든 코드들의 인덴테이션이 깊어 지는 현상을....



(fetcher는 rest call을 해주는 녀식입니다.)


여기서 먼저 rest call을 시도하는데, 실패하게 되면, callback의 failure 메소드를 호출해줍니다. 


그래서 미리 구현한 자동 로그인 처리 콜백을 대신 넣어주고, 이때 원래의 콜백을 생성자에 넣어 원래대로 성공시엔 원래의 콜백을, 그렇지 않고 실패시, 로그인을 시도하고 성공시 원래의 콜백을 다시 호출해 주는 형태입니다.


이것을 깔끔하게 할 방법이 없을까....하는 생각에 다이내믹 프록시를 써볼까도 생각해 봤지만 이왕 하는거 AspectJ를 사용해보기로 합니다. (다이내믹 프록시가 인터페이스에만 되는...? 이쪽은 좀 더 공부를 해봐야 할것 같아..)


stackoverflow에서 한참 뒤져보았지만... 제대로 되는게 없었는데,.,,,


https://github.com/uPhyca/gradle-android-aspectj-plugin


여기 간단하게 aspectj 를 사용할 수 있도록 해주는 플러그인이 이미 존재...허....바로 되네요...


자신의 프로젝트의 build.gradle을 아래와 같이 dependencies하고  configurations을 추가해줍니다.



build.gradle


repositories {

mavenCentral()

}


buildscript {

repositories {

mavenCentral()

}

dependencies {

classpath 'com.android.tools.build:gradle:0.12.2'

classpath 'com.neenbedankt.gradle.plugins:android-apt:1.2+'

classpath 'com.uphyca.gradle:gradle-android-aspectj-plugin:0.9.+'

}

}


apply plugin: 'com.android.application'

apply plugin: 'android-aspectj'


android {

    compileSdkVersion 20

    buildToolsVersion "20.0.0"


    defaultConfig {

        applicationId "com.flask.aspectjtest"

        minSdkVersion 16

        targetSdkVersion 20

        versionCode 1

        versionName "1.0"

    }

    buildTypes {

        release {

            runProguard false

            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'

        }

    }

lintOptions {

abortOnError false

}

}


configurations {

ajc

aspects

ajInpath

}


ext.aspectjVersion = '1.8.2'


dependencies {

    compile fileTree(dir: 'libs', include: ['*.jar'])

compile 'com.android.support:appcompat-v7:20.0.0'

}



굉장히 간단하게 되는지 테스트 해보기 위해, 



간단한 어노테이션을 먼저 만들고(런타임에도 유효한 메소드에 붙일 수 있는)




관점을 만들고 @Around 어노테이션으로 메소드 실행전/후에 하고싶은것을 넣어주었습니다. 




그리고 엑티비티 클래스에서 메소드에 정의한 어노테이션을 붙여줍니다.


실행을 하면 아래와 같은 결과가 나타납니다.




AspectJ 공부: http://www.egovframe.go.kr/wiki/doku.php?id=egovframework:rte:fdl:aop:aspectj











저작자 표시 비영리 변경 금지
신고
크리에이티브 커먼즈 라이선스
Creative Commons License

'[+++ JAVA +++] > - - 작성중' 카테고리의 다른 글

AndroidStudio with Robolectric  (0) 2014.12.02
AndroidStudio Gradle + AspectJ  (0) 2014.10.03
AngularJs - 2  (0) 2014.08.05
Mocha - Javascript test framework  (0) 2014.07.23
Trackback 0 Comment 0
2013.11.08 20:12

Gradle + AndroidStudio + AndroidAnnotations with two different product flavor(diifferent packgename)


안드로이드에서 제일 짜증나고 불편하고 반복적인 작업이 바로 R 클래스, 그러니까 리소스 사용에 관련된 모든것을 R.java 에 접근해서 사용하는 것입니다.


이때 이것을 자동화? 또는 좀더 가독성이 좋고 유지보수하기 좋게 해주는것이 바로 AndroidAnnotations, Roboguice 등이 있습니다. 물론 저런 뷰 Injection 말고도 다른 기능들 rest, async, event처리등 굉장히 많은 편리한 기능들을 내포하고 있습니다.


http://androidannotations.org/

https://github.com/excilys/androidannotations

https://code.google.com/p/androidannotations/wiki/FAQ

https://github.com/excilys/androidannotations/issues/690

https://github.com/excilys/androidannotations/issues/517

https://github.com/excilys/androidannotations/issues/676

http://stackoverflow.com/questions/17910603/android-studio-gradle-android-annotations/17999249#17999249

어노테이션 프로세서관련 stackoverflow 답변

http://stackoverflow.com/questions/19351168/gradle-annotations-flavors-wont-run-annotations-processor

메이븐 셋팅

https://github.com/excilys/androidannotations/wiki/Maven


이번에는 AndroidStudio에서 gradle로 빌드할때 아래와 같은 조건일때 빌드하는 방법을 포스팅 하려고 합니다. 한 4일? 간 삽질해서 알아낸...멍청하네요.ㅋㅋ


1. AndroidAnnotations 를 사용한다.

2. Gradle 빌드에서 두가지 서로다른 product flavor가 존재한다.

3. 각 product flavor에는 pckage name이 조금씩 다르다.

(ex, free버전에는 패키지네임 뒷부분에 **.**.**.free가 붙는다)


먼저 AndroidAnnotations는 컴파일 시간에 미리 관련 뷰들을 바인딩 해줘서 런타임에서 속도 저하 없이 사용할 수 있고, Roboguice는 런타임에? 하는걸로 알고 있습니다. (이 부분에 대해서 자세히 아시는 분은 지적해 주시면 감사하겠습니다.)


따라서 컴파일 타임에 뭔가를 하는데 이름에서도 나타내듯이 어노테이션을 사용하게 됩니다.

즉, @~~~~~뭐 이런것을 사용한단 말이죠. JUnit 에서 @Test 처럼 미리 정의된 어노테이션을 가지고 뷰를 바인딩 하게 됩니다. 

그리고 컴파일시에 자바의 어노테이션 프리프로세서를 통해서 어노테이션을 사용한 클래스를 상속받아 새로 클래스를 만들게 되고 여기서 바인딩이 이뤄지게 됩니다.


첫번째 문제는 새로 클래스(엑티비티)를 생성하기 때문에 기존의 이름을 사용할 수 없습니다. 따라서 AndroidAnnotations에서는 이름 뒤에 언더스코어, '_' 이것을 붙여서 구분하게 됩니다.

즉, AndroidManifest.xml 에서 엑티비티를 정의할때 '_' 를 추가해야합니다.

Intent를 사용할때도 위와 같습니다.


두번째 문제는, 이 바인딩이 이뤄질때 onCreate에서 바로 뷰들을 사용할 수 없습니다. 이때 사용하게되면 바인딩이 아직 이뤄지지 않았기 때문에 NullPointerException 이 나게 됩니다.

따라서 바인딩이 다 된 시점에야 뷰들을 초기화 하고 사용할 수 있는데 이것을 콜백으로 받아오는 어노테이션이 바로 @AfterViews 입니다. 즉 이 어노테이션이 붙은 매소드에서 바인딩이 다 된후에 호출하게 되고 뷰에 대해서 접근할 수 있습니다. 따라서 onCreate 매서드에는 거의 바디가 조촐합니다.


첫번째 링크에서 보다시피 굉장히 매소드들, 필드들이 굉장히 가독성이 좋게 되고 유지보수 펴하게 되어있으며 코드 또한 간결하게 됩니다. 이렇게 뷰에 대한 반복적인 작업만 없앴는데도 상당히 편해졌다는것을 알 수 있습니다.


이정도만 AndroidAnnotations 설명을 마치고 이제 본격적인 Gradle 과의 연동?에 대한 내용입니다.


먼저 메이븐으로 의존성 관리를 하고 있으면 좋습니다. 따라서 AndroidStudio에서 의존성을 추가해주는데 이때 중요한것이 최신버전이 아닌 스냅샷 버전을 사용할것입니다.

현재 최신버전이 2.7.1 인거 같은데 최신버전에 없는 컴파일 인자를 사용하기에 3.0 SNAPSHOT을 사용하도록 합니다. (여기서 굉장히 삽질한것이, build.gradle에 정의한 AA버전과 메이븐의 AA버전이 안맞아서....이틀간....-_-)


그런뒤 build.gradle에 아래와같이 추가해줍니다.


ext.daggerVersion = '1.0.0';

androidAnnotationsVersion = '3.0-SNAPSHOT';

repositories {

mavenCentral()

maven {

url 'https://oss.sonatype.org/content/repositories/snapshots/'

}

}

android {

productFlavors {

paid {

packageName "com.my.app"

}

free {

packageName "com.my.app.free"

}

}

}

android.applicationVariants.all { variant ->

aptOutput = file("${project.buildDir}/source/apt_generated/${variant.dirName}")

println "****************************"

println "variant: ${variant.name}"

println "manifest:  ${variant.processResources.manifestFile}"

println "aptOutput:  ${aptOutput}"

println "****************************"


variant.javaCompile.source = variant.javaCompile.source.filter { p ->

return !p.getPath().startsWith(aptOutput.getPath())

}


variant.javaCompile.doFirst {

println "*** compile doFirst ${variant.name}"

aptOutput.mkdirs()


variant.javaCompile.options.compilerArgs += [

'-classpath', configurations.compile.asPath,

'-processorpath', configurations.apt.getAsPath(),

'-AandroidManifestFile=' + variant.processResources.manifestFile,

'-AresourcePackageName=com.my.app',

'-s', aptOutput

]

}

}

configurations {

apt

}

dependencies {

compile "com.android.support:support-v13:13.0.0"


apt "org.androidannotations:androidannotations:${androidAnnotationsVersion}"

compile "org.androidannotations:androidannotations-api:${androidAnnotationsVersion}"


apt "com.squareup.dagger:dagger-compiler:${daggerVersion}"

compile "com.squareup.dagger:dagger:${daggerVersion}"

}

* androidannotations.jar 은 딱 컴파일 할때 필요한, 즉 어노테이션 프로세서가 있는 jar이고,
실제 우리가 써야 하는건  androidannotations-api 인듯. 이틀간 이거때문에 삽질 함


여기서 스냅샷을 사용하는 이유가 바로 free버전의 패키지 네임이 다르기 때문입니다.

만악 스냅샷이 아닌 최신버전을 사용하게 되면(물론 나중의 최신버전엔 기 인자가 포함될 수 있겠죠), 


*** compile doFirst FreeDebug

Note: Starting AndroidAnnotations annotation processing

Note: AndroidManifest.xml file found: */build/manifests/free/debug/AndroidManifest.xml

warning: The AndroidManifest.xml file was found, but not the compiled R class: com.my.app.free.R

/SettingViewPagerActivity.java:30: error: Resource id value not found in R.id: 2131165208

@ViewById(R.id.pager)

^

Note: Number of files generated by AndroidAnnotations: 1

Note: Generating source file: com.my.app.activity.SettingViewPagerActivity_

Note: Time measurements: [Whole Processing = 135 ms], [Process Annotations = 63 ms], [Validate Annotations = 31 ms], [Extract Annotations = 13 ms], [Generate Sources = 12 ms], [Find R Classes = 9 ms], [Extract Manifest = 5 ms],

Note: Time measurements: [Whole Processing = 0 ms],

warning: The following options were not recognized by any processor: '[androidManifestFile, resourcePackageName]'

1 error

1 warning

:MyApp:compileFreeDebug FAILED


처럼 실패하게 됩니다. 이유는 R.class를 찾아야 하는데 못찾아서 해당 리소스를 가져오지 못해 에러가 납니다.

그러면 어떻게 R.class를 찾아야 하나...? 보면 R을 com.my.app.free.R 인줄 알기 때문입니다.

즉 product flavor에서 package name을 정의한대로 찾아가기 때문입니다.

그래서 -AresourcePackageName=com.my.app 이 인자를 사용해서 고정해주게 됩니다.


이 인자가 얼른 최신버전에 반영이 되기를 바랍니다.




저작자 표시 비영리 변경 금지
신고
크리에이티브 커먼즈 라이선스
Creative Commons License
Trackback 0 Comment 0


티스토리 툴바