AAPT2 error: check logs for details

AAPT2 error: check logs for details

안드로이드 스튜디오 버전 업데이트 이후 다음과 같은 버그를 만났다. Error:com.android.tools.aapt2.Aapt2Exception: AAPT2 error: check logs for details Gradle 3.0에서 aapt대신 aapt2를 기본적으로 사용하면서 나타나는 버그이며 가장 많이 말하는 해결책은 gradle.properties에서 android.enableAapt2=false를 추가해 aapt2를 사용하지 않는것이다. 하지만 이는 임시방편일뿐 결국엔 aapt는 deprecate되고 aapt2를 사용해야한다. Gradle용 Android 플러그인 3.0 마이그레이션 가이드라인 마이그레이션 문서가 별로 길지 않으니, 꼭 마이그레이션을 진행하는게 좋다. 9-patch 이미지 파일 빌드중 에러메시지에 .9.png 이 포함되어 있다면, 앱 내 9 patch 이미지 파일중 잘못 만들어진 파일이 있다는 의미이다. .9 를 빼고 빌드해 본 뒤 빌드에 성공하면 해당 이미지 파일을 다시 만들어준다. (2번이 문제일 확률이 높다)

April 6, 2018 · Juyeong Lee

[Gradle] Could not determine java version from 문제 해결

Could not determine java version from '9.0.4' JDK9을 설치한 이후로 ./gradlew를 실행하면 해당 에러가 발생한다. ./gradle/wrapper/gradle-wrapper.properties파일을 열어보니 gradle 4.1버전을 사용중 4.3.1버전 이상으로 업데이트하면 문제가 해결된다. #Sat Feb 24 17:55:43 KST 2018 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists distributionUrl=https\://services.gradle.org/distributions/gradle-4.3.1-all.zip 출처 gradle 홈페이지 => 4.3버전 이상으로 업데이트 한 이후 해당 에러가 사라졌다고 한다.

March 15, 2018 · Juyeong Lee
[안드로이드] Resources Naming Rule

[안드로이드] Resources Naming Rule

같은 프로젝트를 오랫동안 개발하다 보면 drawable이나 layout 같은 리소스명이 규칙 없이 생성되게 된다. 여러 사람이 개발하거나, 내 마음이 바뀌거나… 리소스 작명 규칙을 정해놓고 그 규칙을 따르다 보면 가독성이 높아진다. Basic Principle [what]_[where]_[description]_[size] what activity, fragment … where main, user, settings … description title, content, profile … size 24dp, small … (optional) Layout [what]_[where].xml activity, fragment, view , item, layout 예시 activity_main.xml, layout_article.xml Strings [where]_[description] 공통적인 문자열은 [where]에 all 또는 common을 사용 예시 article_title, common_purchase Drawables [where]_[description]_[size] 공통 이미지는 all, common을 사용 예시 noti_icon_24dp Ids [what]_[where]_[description] 예시 tablayout_main, imageview_menu_profile Dimensions [what]_[where]_[description]_[size] waht은 width, height, size, margin, padding같은 것들이 들어갈 수 있다. 예시 height_toolbar, size_profile 한계점 모든 화면이 다른 이름을 가져야함 (MainActivity, MainFragment는 같은 main을 사용하기 때문에 충돌이 일어날수 있음) 리펙토링이 자동으로 되지는 않음 출처: http://jeroenmols.com/blog/2016/03/07/resourcenaming/

April 5, 2017 · Juyeong Lee
[안드로이드 Lint] Incompatible Gradle Versions

[안드로이드 Lint] Incompatible Gradle Versions

안드로이드 스튜디오 버전을 2.3으로 업데이트한 후 support package를 추가하면 다음과 같은 린트 에러가 발생합니다. compile "com.android.support:support-v4:25.2.0" All com.android.support libraries must use the exact same version specification (mixing versions can lead to runtime crashes) 문제는 내가 명시하지 않은 support package를, 외부 라이브러리에서 사용하는 것입니다. . Facebook SDK 예를 들어 Facebook SDK를 사용중이라면, Facebook SDK내부에서 support package를 참조하고 있습니다. +- com.facebook.android:facebook-android-sdk:4.20.0 | +- com.android.support:support-v4:25.0.0 -> 25.2.0 (*) | +- com.android.support:appcompat-v7:25.0.0 -> 25.2.0 (*) | +- com.android.support:cardview-v7:25.0.0 | | \- com.android.support:support-annotations:25.0.0 -> 25.2.0 | +- com.android.support:customtabs:25.0.0 -> 25.2.0 (*) Facebook SDK에서는 support package 25.0.0을 사용중입니다. support-v4, appcompat-v7, customtabs는 최신버전인 25.2.0로 대체되었지만, cardview-v7은 25.0.0을 사용중입니다. ...

March 13, 2017 · Juyeong Lee
[Android] TextView에서 textIsSelectable 이 동작하지 않는 현상

[Android] TextView에서 textIsSelectable 이 동작하지 않는 현상

1. TextView 내의 글자 선택하기 xml내에서 textIsSelectable을 true로 설정해준다. <TextView android:id="@+id/text" android:layout_width="match_parent" android:layout_height="wrap_content" android:textIsSelectable="true" android:text="Hello World!" /> java코드에서 setTextIsSelectable을 true로 설정 해준다. mTextView.setTextIsSelectable(true); 위 두가지 중 한가지만 적용해주면 TextView의 글자를 선택해 복사 할 수 있다. 2. ListView(RecyclerView) 에서의 이슈 QA를 하던 중 TextView의 글자를 선택할 수 없다는 말을 들었다. 처음에는 롱클릭이 잘 되지만, 스크롤을 내리면 텍스트를 선택할 수 없다는 것이었다. 3. 해결방법 TextView를 상속받아서 View가 attach되는 시점에 disable -> enable을 시켜주면 해결 된다. (http://stackoverflow.com/a/38626276) ...

December 28, 2016 · Juyeong Lee

[Java] ExecutorService

Executor 제출된 Runnable task를 실행하는 객체. ExecutorService 하나 이상의 비동기 task의 진행상태를 추적하기위한 Future를 생성하는 메소드 를 제공하는 Executor. ExecutorService 예제1 간단한 ExectorService 사용법. ExecutorService executorService = Executors.newFixedThreadPool(10); executorService.execute(new Runnable() { public void run() { System.out.println("Asynchronous task"); } }); executorService.shutdown(); Executors.newFixedThreadPool() 라는 팩토리 메소드를 통해 10개의 스레드 풀을 사용하는 executorService를 만들고 "Asynchronous task"라는 내용을 출력한 뒤 종료. ExecutorService를 모두 사용한 뒤에는 자원 반납을 위해 반드시 종료해야하며 종료를 위해 두 개의 메소드shutdown(), shutdownNow() 가 제공된다. ...

February 21, 2016 · Juyeong Lee
[Android] Avoid passing null as the view root

[Android] Avoid passing null as the view root

LayoutManager로 직접 View를 생성할때 가끔 이런 경고를 볼 수 있다. LayoutInflater는 View를 생성할때 자신의 레이아웃을 잡기위해 부모 View가 필요하다. 이때 부모 View를 알려주지 않으면 (null을 넘기면), 부모를 알 수 없기 때문에 layout xml에 정의한 android:layout_xxxxx 값들은 모두 무시된다. <GridView android:id="@+id/grid" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_margin="10dp" android:padding="5dp" android:visibility="invisible" android:numColumns="2" /> 지금 보는 GridView에서는 layout_width, layout_height, layout_margin이 무시되고 padding, visibility, numColumns는 적용 됨. ...

February 21, 2016 · Juyeong Lee
안드로이드 LayoutInflater 사용하기

안드로이드 LayoutInflater 사용하기

안드로이드에서 레이아웃 XML파일을 View객체로 만들기 위해서는 LayoutInflater를 이용한다. LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); View view = inflater.inflate(R.layout.my_layout, parent, false); 이렇게 간단하게 사용 할 수 있다. LayoutInflater 생성하기 1. Context#getSystemService() LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); View view = inflater.inflate(R.layout.my_layout, parent, false); 2. Activity#getLayoutInflater() LayoutInflater inflater = getLayoutInflater(); 액티비티에서는 LayoutInflater를 쉽게 얻어올수 있도록 getLayoutInflater() 메소드를 제공한다. 엑티비티의 윈도우에 있는 getLayoutInflater()로 포워딩 해준다. // android/app/Activity.java public LayoutInflater getLayoutInflater() { return getWindow().getLayoutInflater(); } 3. LayoutInflater.from() LayoutInflater inflater = LayoutInflater.from(context) View view = inflater.inflate(R.layout.my_layout, parent, false); LayoutInflater에서는 LayoutInflater를 쉽게 생성 할 수 있도록 static factory 메소드 LayoutInflater.from()을 제공한다. (내부적으로 getSystemService를 호출함) ...

February 21, 2016 · Juyeong Lee

지니모션에서 로컬호스트 서버 접근하기

Accessing a localhost server from the Genymotion Android emulator 안드로이드 에뮬레이터인 제니모션(Genymotion)을 사용하다가 로컬에서 돌리 서버에 접속할 일이 생겼다. 제니모션은 버츄얼박스를 이용해서 에뮬레이터를 사용하기때문에 제니모션에서의 localhost와 컴퓨터의 localhost가 다르다. ifconfig vboxnet0 또는 ipconfig vboxnet0 를 이용하여 호스트의 주소를 알아내서 사용하면 된다 일반적으로는 192.168.56.1 일 것이다. 그래도 동작하지 않는다면 10.0.3.2를 사용하면 동작한다고…. (제니모션 와이파이 DHCP주소가 10.0.3.2로 나옵니다.) 요약 제니모션에서 로컬호스트 서버에 접근하려면 ip주소를 localhost, 127.0.0.1대신 192.168.56.1 또는 10.0.3.2로 시도해보면 된다! 참고자료 - http://bbowden.tumblr.com/post/58650831283 홈페이지 - https://www.genymotion.com/ 제니모션.? 지니모션.? 유튜브에선 제니모션이라고 하던데.. 한국어 블로그는 지니모션 뿐이다..

February 4, 2016 · Juyeong Lee
안드로이드 시간 측정

안드로이드 시간 측정

성능 측정 long startTime = getCurrentTime(); // do something long endTime = getCurrentTime(); Log.d(DEBUG, "elapsedTime : " + (endTime - startTime)); 일반적으로 성능을 측정할때는 어떤 기능을 수행하는데 걸리는 시간을 측정합니다. 안드로이드에서도 역시 어떤일을 하는데 시간이 얼마나 소요되었는지를 측정해야 할 때가 있습니다 예를 들면 이 코드는 어떤 기능을 수행하는데 소요된 시간을 보여줍니다. Java Java에서는 시스템의 시간을 가져오는데 기본적으로 System.currentTimeMillis(), System.nanoTime()을 제공합니다. System.currentTimeMillis() System.currentTimeMillis()은 1970/1/1 00:00:00 UTC을 기준으로 현재 시간을 리턴합니다. 시스템의 TimeZone에 관계없이 항상 UTC 시간을 리턴하기 때문에 보통 “Unix time”, “epoch time"이라고 부릅니다. System.currentTimeMillis()는 시스템의 시간을 가져오지만, 시스템의 시간은 언제든지 변경될수 있기 때문에 시간 측정에는 적합하지 않습니다. (ACTION_TIME_TICK, ACTION_TIME_CHANGED, ACTION_TIMEZONE_CHANGED과 같은 브로드캐스트에 의해 시간이 변경되는걸 알 수 있습니다.) ...

February 4, 2016 · Juyeong Lee