카테고리 : android
-
Could not find com.android.support.constraint:constraint-layout 오류 해결
안드로이드에서 ConstraintLayout를 사용하기 위해 아래와 같이 gradle에 설정했었다. dependencies { compile 'com.android.support.constraint:constraint-layout:1.0.0-alpha9' } 업데이트가 있는지 확인해 보니 1.0.1이 있기에 아래와 같이 변경했다. dependencies { compile 'com.android.support.constraint:constraint-layout:1.0.1' } 그리고 빌드를 해려고 했더니 아래와 같은 오류가 났다. E
-
Theme.NoDisplay 테마 사용시 안드로이드 API 23에서 did not call finish() prior to onResume() completing 오류 발생
눈에 보이지 않는 Activity를 생성하기 위해 "Theme.NoDisplay" 테마를 사용한 앱에서 오류가 발생했다. 오류 내용을 보면 onResume()이 호출되기 전에 finish()가 호출되지 않았다는 것이다. 확인해보니 "Theme.NoDisplay" 테마가 사용된 Activity는 윈도우 자체가 생성되지 않기 때문에 onResume()이 호출되기 전에 finish()가 호출되어야 하는 조건이 있다. 예를들면 아래와 같다. public class NoDisplayActivity extends Activity { @Over
-
Android 투명 / 보이지 않는 Activity 만들기(Theme.Translucent / Theme.NoDisplay)
안드로이드에서 투명한 배경을 가진 Activity나 눈에 보이지 않는 Activity를 만드는 방법 중 가장 쉬운 방법은 Activity의 Theme를 사용하는 것이다. 이러한 Activity를 구성하기 위해 안드로이드에서 제공되는 테마 몇가지를 알아보자. 아래에 나오는 각 테마의 설정 내용은 Android SDK 24 기준임을 참고하기 바란다. Theme.Translucent Theme.Translucent 테마는 안드로이드 3.0 이전부터 존재한 테마로 투명한 배경을 가진 Activity를 만들때 사용할 수 있는 테마다. 일반적
-
OSX에서 Facebook redex 사용시 Error writing mapping file: No such file or directory 오류 해결
안드로이드 앱을 개발하면서 redex를 이용해 최적화를 하고 있다. 이미 proguard를 사용하고 있기 때문에 용량에서는 큰 차이가 나지 않지만 성능면에서 도움이 된다고 소개하고 있어 사용하는 것이다(체감으로는 잘 느끼지 못하겠다). 그런데 오늘 redex에서 오류가 발생했다. Error writing mapping file: No such file or directory 정확히는 내 작업 PC가 아닌 동료의 PC에서 redex를 사용하면서 발생했다. 내 작업 PC에서는 이상이 없어서 확인을 하던 중 redex의 버전 문제인가?
-
안드로이드 스튜디오에서 디바이스 연결이 끊어질 경우 다시 연결하는 방법
안드로이드 앱을 개발시 에뮬레이터를 사용하는 경우도 있으나 대부분의 경우는 실제 기기를 연결해서 작업하는 경우가 많다. 기존 에뮬레이터의 경우 너무 느린 속도와 호환 문제로 잘 사용하지 않는다. 최근 성능과 안정성이 많이 개선 되었다고는 하나 아직 여러가지 문제가 있다(예를들어 vagrant와 동시에 사용할 수 없다). 기기를 사용해서 작업하는 경우 거추장스러운 선을 제거하기 위해 WIFI를 연결해서 디버깅하는 경우(안드로이드 스튜디오에서 WIFI로 Run/Install/Debug 하기)도 있으나 연결의 귀찮음과 안정성 문제로 직접
-
Google Service Library 9.6.0 사용시 READ_PHONE_STATE 권한이 추가되는 문제
최근 서비스 중인 앱에서 사용중이던 Google Service Library의 버전을 최신 버전으로 변경했다. 기존에 사용중이던 버전은 9.2.1 이었다. 얼마전 9.4.0으로 변경된 것을 확인하고 9.4.0을 적용했다. debug 모드와 release 모드에서의 동작을 확인한 후 "베타 테스트"에 올려 보니 이상하게도 모든 테스트 기기에서 앱이 응답하지 않는 문제가 확인되었다. 오류 보고나 기록이 나타나는 것도 아니어서 문제 확인이 어려웠고 처음엔 다른 작업 중에 변경한 코드들에서 원인이 있을 것이라고 추측 했었다. 하지만 많은
-
안드로이드 WebView에서 HTML5 Video Full Screen 지원
안드로이드 WebView에서 HTML5 Video를 재생할 경우 "전체창으로 보기"를 사용할 수 있다. 그런데 자동적으로 사용할 수 있는 것이 아니라 관련된 처리를 직접 해주어야 한다. 필요한 처리는 아래와 같다. WebView에 WebChromeClient를 설정해 주어야 한다. 그렇지 않으면 4.0 이후에서 NullPointerException이 발생한다. WebChromeClient를 설정하더라도 [onShowCustomView()](https://developer.android.com/reference/android/webk
-
안드로이드 WebView resumeTimers() / pauseTimers() 적용하기
안드로이드의 WebView를 사용하다 보면 처음 페이지를 보여줄 때는 정상적으로 보이나 두 번째 이후부터 페이지를 정상적으로 표시하지 못하는 경우가 있다. 이 경우는 여러가지 이유로 발생할 수 있으나 오늘은 pauseTimers / resumeTimers 때문에 발생하는 경우에 대한 이야기를 하고자 한다. 우선 이 함수들이 필요한 이유부터 간단히 알아보자. 메뉴얼에서 pauseTimers를 찾아보면 아래와 같이 설명되어 있다. Pauses all layout, parsing, and JavaScript timers for all W
-
Android 4.4.3, 4.4.4 Webview Referer 오류 수정
안드로이드 WebView를 사용하면서 특정 페이지로의 접근시 Referer를 지정해서 넘기도록 처리해서 사용중인 앱이 있다. 그런데 테스트 도중 이상한 문제가 발생했다. Android 4.4.4에서만 지정한 Referer를 무시하고 넘기지 않는 것이다. 그래서 조금 찾아보니 아래와 같은 글들이 있었다. Webview/UIWebview Header에 HTTP Referer 추가 Android OS 4.4 이상의 단말에서는 Webview가 Chromium기반으로 변경되면서 Referer 추가해도 HTTP Header에 설정이 되지 않는
-
Html.fromHtml deprecated(Android N)
Android N이 아직 developer preview 상태지만 곧 정식 버전이 나올 것으로 생각된다. 이 Android N에서 deprecated 된 것 중의 하나가 Html.fromHtml다. 공식 문서에는 다음과 같이 안내되어 있다. This method was deprecated in API level 24. use fromHtml(String, int) instead. 이와 관련해서는 길게 이야기할 것도 없으니 버전에 대응되도록 처리해 둔 함수를 아래에 남긴다. public static Spanned fromHtml(St
-
android Uri.getQueryParameter() 사용시 젤리빈 이전 버전에서 공백이 +로 표시되는 문제 해결
Uri.getQueryParameter() 사용시 젤리빈 이전 버전을 지원해야 한다면 주의해야 할 사항이 있다. 최근에는 젤리빈 이하를 굳이 지원할 필요가 없다고 볼 수 있지만 혹시라도 지원해야 한다면 아래의 내용을 참고하자. 공식 문서에서 보면 해당 함수 설명에 아래의 내용이 있다. Warning: Prior to Jelly Bean, this decoded the '+' character as '+' rather than ' '. 젤리빈 이전 버전에서는 공백을 urlencode하여 넘겨진 +를 공백으로 치환하지 않는다. 따라서
-
안드로이드 : TextView 터치시 가로 스크롤이 되지 않는 문제 수정(ViewPager 등에서)
오늘도 역시 안드로이드는 실망시키지 않는다. 오늘의 문제는 이렇다. 가로 스크롤되는 ViewPager의 Item View에 TextView가 포함되도록 구성되어 있을 경우 TextView 위에서 터치를 하면 가로 스크롤이 동작하지 않는 문제가 발생한다. 조금 더 정확히 이야기하자면 singleLine 속성이 true로 설정된 TextView들이 가로 스크롤을 정상 동작하지 않도록 만든다. 처음엔 click 이벤트로 인한 문제로 생각했다. 실제로 아래에 깔린 View의 click 이벤트를 제거하니 스크롤이 정상적으로 동작했다. 그런데
-
Generic Type으로 인스턴스 생성
java에서 Generic Type은 유용하고 다양한 곳에서 사용한다. 예를 들어 안드로이드에서 findViewById 사용시 Generics을 이용해 Type Casting 없애기처럼 사용도 가능하다. 이 글의 주제는 Generic Type으로 해당 class의 인스턴스를 얻는 방법에 대한 것이므로 Generic Type에 대한 기본적인 내용은 다루지 않는다(설명이 길다). 우선 class로 인스턴스를 생성하는 가장 기본적인 방법부터 보자. Class clazz = String.class; try { String a = (Stri
-
com.google.gson.JsonSyntaxException: java.lang.NumberFormatException: Expected an int but was 오류
GSON을 이용해서 JSON 데이터를 Parse하려고 할 때 아래와 같이 NumberFormatException이 발생할 수 있다. 이는 대부분의 경우 int의 최댓값을 넘어선 값을 int에 대입하려고 할 때 발생한다. com.android.volley.ParseError: com.google.gson.JsonSyntaxException: java.lang.NumberFormatException: Expected an int but was 4291611852 at line 1 column 143 path $.items[0].item
-
android gradle provided와 org.apache.http.legacy
이 글은 사실 주제가 명확하지 않다(제목도 그러하듯). 경험을 나열한 것에 불과할지도 모른다. 하지만 Volley와 Glide, gradle provided, org.apache.http.legacy.jar 파일을 얻는 법 등의 내용을 포함하고 있어서 다른 작업시에도 부분적으로 도움이 될 수 있을 것 같아 글을 남긴다. Android 6(API 23 : marshmallow) : Apache HTTP 클라이언트 제거에서 안드로이드의 Apache HTTP 클라이언트에 대한 지원을 제거함에 따른 대응 방법을 안내했었다. 그런데 오늘은
-
Android Studio : Find results에서 build files 제외하기
Android Studio로 작업을 하다보면 많은 불편함을 겪게 된다. 그중에 하나가 원하는 문자열을 찾기 위해 사용하는 "Find in Path"(Command+Shift+F / Ctrl+Shift+F) 메뉴다. PHPStorm은 exclude 기능을 이용해서 원하지 않는 폴더를 프로젝트에서 제외해 둘 수 있다. 같은 회사에서 만들었음에도 불구하고 Android Studio에는 비슷한 기능이 없다. 그로 인해서 Find로 프로젝트 전체에서 검색시 build 폴더 등이 포함되어 원하는 결과를 찾기가 무척 힘들다(특히 R.java,
-
Android : Error:Could not read entry ':app:processDebugManifest' from cache taskArtifacts.bin 오류 수정
안드로이드 빌드시 아래와 같은 오류가 날 때가 있다. Error:Could not read entry ':app:processDebugManifest' from cache taskArtifacts.bin ~~~ 흔하게 발생하지는 않는데 프로젝트의 Gradle 버전을 변경하는 경우 간혹 발생할 수 있다. 해결 방법은 대부분 아주 간단하다. 오류 내용 중 from cache taskArtifacts.bin에서 보듯이 cache 파일에서 필요한 정보를 가져오지 못하고 있으니 해당 cache 파일을 지우면 된다. rm .gradle/2.1
-
안드로이드에서 Soft Navigation Bar 검사하기
안드로이드 기기 중에는 Soft Navigation을 사용하는 것들이 있다. 보통은 뒤로, 메뉴, 홈 버튼 등이 스크린과 분리되어 물리적 버튼으로 구성되어 있으나 이 버튼들이 스크린 하단 영역에 포함되어 있는 경우다. 이런 기기에서는 상황에 딸 하단의 버튼 영역을 숨겨 보다 넓은 공간을 스크린으로 활용할 수 있다. 여기서 다루고자 하는 것은 이런 물리 버튼을 가진 기기와 Soft Navigation을 사용하는 기기를 구분하는 방법이다. 관련 정보를 찾아보면 명확하게 구분할 수 있는 방법을 제시하는 곳을 찾기가 어렵다(안드로이드에서
-
Charles를 이용한 안드로이드 SSL Proxy
안드로이드 앱을 개발할 때 http/https 디버깅을 위해서 proxy를 사용한다. 나는 예전에 Paros를 주로 사용했었는데 기본적인 기능을 사용하는데 문제가 없지만 버전업이 중단되어 아쉬운 부분이 많았다. 그래서 최근엔 Charles를 주로 사용한다. Paros와 달리 Charles는 유료지만 사용이 편리하고 다양한 기능을 제공한다. 그래서 많은 사람들이 사용하고 있는 것 같다. 이번에는 이 Charles를 이용해서 https(SSL)를 proxy하는 방법을 설명하고자 한다. 이 글의 주요 주제는 아니지만 Charles를 이용
-
안드로이드 앱 종료 방법
안드로이드에서 앱의 종료는 보통 Root Activity에서 finish()를 사용한다. 그런데 앱의 종료는 이외에도 여러가지 방법이 있고 각각이 다른 상황을 만들어 낸다. 당연히 구글에서는 finish()를 권장한다고 한다. 하지만 상황적으로 프로세스를 완전히 종료해야 하는 경우가 있을 수 있다. 아래에 설명하고자 하는 것들은 안정적으로 사용할 수 있는 방법이라고 장담하지는 못한다. 충분히 테스트된 코드가 아니라 인터넷 상에서 소개되는 방법들을 정리한 것이다. 물론 기본적인 테스트는 했다. 우선 Activity만 종료하는 방법부터
-
안드로이드 Realm 0.82.2 -> 0.86.0 버전업
모바일 앱 개발시에 DB는 주로 Sqlite 또는 Core Data를 많이 사용한다. 그런데 Sqlite 등을 사용하는 것이 조금 불편한 부분들이 많아서 지난 앱 개발시 Realm을 사용했다. Realm을 사용하면 개발이 용이해지기는 한데 간혹 다루기가 까다로워지는 경우가 있다. 사실 그런 문제 상황은 내가 사용시 뭔가를 잘못했을 확률이 높지만 개인적으로 다소 예민한 라이브러리라고 생각한다. 어찌보면 당연할 수도 있는 것이 아직 1.0 버전이 되지도 못한 라이브러리니 그럴만도 하다. 실제로 아직은 버전업이 자주 발생하고 버전업시에
-
안드로이드 Crash Report 도구 : ACRA에서 Fabric(Crashlytics)으로의 전환
지난 글 ACRA : Please configure 'buildConfigClass' in your ACRA config 오류와 Android 6(API 23 : marshmallow) : Apache HTTP 클라이언트 제거에서 언급했던 것처럼 안드로이드 Crash Report 도구로 ACRA를 사용중이었다. ACRA 사용중에 만난 오류를 해결하기 위해 시간을 들여서 원인을 찾고 개발자에게 전달해서 개선을 요청할 정도로 나름 애용하려던 도구였는데 오늘 Fabric(Crashlytics)으로 바꿔버렸다. 사실 처음부터 대체할 목적이
-
Android : is not translated in ... Lint Error 해결
안드로이드에서 배포를 위한 빌드시에 아래와 같은 오류가 발생하는 경우가 있다. 상황에 따라 언어의 종류(en)는 다를 수 있다. Error:(65) Error: "..." is not translated in "en" (English) [MissingTranslation] 이 오류는 말그대로 다국어 지원에 대한 처리가 제대로 되어 있지 않다는 오류이다. 일반적으로 다국어 지원을 위한 별도의 처리를 한적이 없다면 이 오류는 발생하지 않는 것이 당연하다. 하지만 이번에 이 오류를 만나고 찾아보니 많은 개발자들이 이 문제를 겪는 것 같다
-
Android에서 runOnUiThread 작업이 종료 될 때까지 대기하기
아래에서 설명하고자 하는 내용을 뭐라고 표현 해야할지 몰라서 "Android에서 runOnUiThread 작업이 종료 될 때까지 대기하기"라고 글 제목을 정했다. 내용을 요약하자면 thread에서 wait()과 notify()를 이용해서 runOnUiThread 작업이 종료될 때까지 대기하도록 하는 것이다. 쉽게 말해서 runOnUiThread는 main thread에서 처리되므로 비동기로 처리되게 되는데 필요한 작업이 완료되기 전까지 다른 처리를 대기시키는 것이다. 이렇게 설명하는 것도 정확한 설명은 아니다. 그냥 내가 하고자 했
-
android.view.WindowManager$BadTokenException: Unable to add window 오류
안드로이드에서 아래와 같은 오류가 나는 경우가 있다. android.view.WindowManager$BadTokenException: Unable to add window -- token android.os.BinderProxy@420d8488 is not valid; is your activity running? 대부분은 Dialog를 띄우러고 할 때 발생한다. 소스로 보자면 아래와 같은 경우다. new AlertDialog.Builder(context) .setTitle("알림") .setMessage("알림 메시지") .se
-
Android : Spans, a Powerful Concept
안드로이드의 Spannable에 관련된 좋은 글이 있어 번역해 본다. 사실 부족한 영어 실력으로 번역이라기 보다 내용을 옮겨보는 정도라고 생각하면 될 듯하다(의역이 많다). Spans, a Powerful Concept. Jan 31st, 2014 6:09 pm Github Sample : flavienlaurent/spans 최근에, 나는 NewStand 앱과 ActionBar icon의 전환 효과에 대해 블로그에 남겼다. Cyril Mottier는 ActionBar의 title에 Spans을 사용하여 fade in/out하는 우
-
android apk download / decompile 하기
오늘은 Google Play에서 apk 파일을 다운 받는 방법과 apk 파일을 decompile하는 방법을 소개하려고 한다. 일반적인 상황에서는 apk를 받거나 decompile 할 일은 거의 없다. 하지만 안드로이드 개발을 하다보면 필요해지는 경우가 있다. 나의 경우는 ACRA를 이용해서 서비스 앱에서 crash가 발생하면 오류를 보고하도록 해두고 사용한다. 그런데 proguard를 사용해서 난독화가 되어 있다보니 오류 메시지만 보고는 어디에서 발생한 오류인지 확인할 수 없다. 그래서 서비스 중이 apk를 다운 받아 decompi
-
Google play services out of date 오류 해결
오늘 앱 사용자에게서 오류 보고를 받았다. 기타 내용은 생략하고 App crash가 발생한 원인인 Google play services out of date이다. Google play services의 사용기간이 만료되었다는 오류인데 발생 원인은 Google play services 의 버전이 요구되는 버전과 맞지 않기 때문이다. 우선 해결 방법부터 보자. 나의 경우는 아래와 같은 함수를 만들어서 필요한 화면에서 호출하도록 했다. static public boolean checkGooglePlayService(Activity act
-
안드로이드 세로 중앙정렬 Span(VerticalCenterSpan)
SpannableString을 사용하던 중에 사이즈가 다른 두 단어를 세로로 중앙 정렬해야 할 일이 생겼다. 그런데 찾아보니 그런 Span은 없고 비슷한 기능이 있는 것들도 BASELINE 또는 BOTTOM으로만 정렬이 가능했다. 그래서 간단하게 Span 클래스를 하나 만들었다. 단, 주의할 것은 multi line은 지원하지 않는다는 것이다(내가 당장 필요하지 않아서 기능을 구현하지 않았다). VerticalCenterSpan.java import android.graphics.Canvas; import android.graphi
-
안드로이드 SpannableString 합치기
안드로이드에서 TextView, EditText 등에서 문자를 출력할 때 스타일을 지정하기 위해서 SpannableString을 사용한다. 다른 방법으로는 Html.fromHtml을 사용하는 방법도 있으나 결국 내부에서는 SpannableString로 처리된다. 그런데 작업을 하다보면 각각의 SpannableString을 합쳐야할 때가 있다. 이런 경우에 사용할 수 있는 것이 TextUtils.concat 이다. 아래의 예시를 보자. SpannableString styledText1 = new SpannableString("Text
-
java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState 오류 해결
안드로이드 Fragment 작업 중에 java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState 오류가 발생했다. 상황은 이렇다. Fragment를 가진 Activity에서 새로운 Activity를 띄우고 해당 Activity에서 setResult를 통해 값을 반환했다. 새로운 Activity를 열었던 Activity에서는 protected void onActivityResult(int requestCode, int resultCode,
-
안드로이드 TabLayout 사용시 Tab Text가 두줄로 나오는 문제 해결
TabLayout에 대한 사용법은 Google Play Style Tabs using TabLayout에 잘 나와 있으므로 생략한다. 안드로이드의 TabLayout 사용시 Tab 안의 Text가 두줄로 나오는 문제가 있다. 정확하게 이야기하자면 Desigon Support Library 23.0.1 미만에서 문제가 있다(자세한 내용은 아래에서 설명한다). 예를들어 아래와 같은 경우다. 위 이미지는 Remove line break in TabLayout에서 질문을 위해 올린 이미지인데 새로 캡춰해서 넣기 귀찮아서 복사해 왔다. 이 글
-
java.lang.IllegalStateException: Recursive entry to executePendingTransactions 오류
안드로이드 작업중 java.lang.IllegalStateException: Recursive entry to executePendingTransactions 오류를 만났다. 오류가 발생한 상황은 다음과 같다. 작업중 Fragment에서 하위에 또 다른 Fragment를 추가할 일이 생겼다. 이 작업 중에 하위에 추가되는 Fragment에서 executePendingTransactions() 함수를 호출하니 위 오류가 발생했다. 이해를 위해 처리 과정 중 문제가 발생한 부분만 적는다. FragmentManager ft = getAc
-
안드로이드에서 인턴트 호출시 Intent.FLAG_ACTIVITY_CLEAR_TOP 또는 Intent.FLAG_ACTIVITY_SINGLE_TOP 사용시 Androidannotations @Extra가 동작하지 않는 문제
Androidannotations를 사용하면 @Extra를 사용해서 인자를 받을 수 있다. 그런데 여기서 주의할 점이 있다. 인턴트 호출시 Intent.FLAG_ACTIVITY_CLEAR_TOP 또는 Intent.FLAG_ACTIVITY_SINGLE_TOP를 사용하게되면 인턴트가 이미 존재할 경우 @Extra가 동작하지 않는다. 이와 관련해서 Always call #onNewIntent(), even without @AfterExtras method(s)에서도 이슈가 진행중이다. 앞서 이야기한 문제와 이 이슈는 정확하게 같은 내용은
-
Google Play services 와 DEX method limits 문제
Android Gradle 빌드 속도 높이기에서 잠시 언급했던 multidex와 Google Play services와의 관계에 대해서 잠시 이야기 하고자 한다. 그 당시에도 설명했던 것과 같이 multidex를 사용해야 하는 상황은 가급적 피하는 것이 좋다. 하지만 오래된 버전의 Google Play services를 사용하면 65K이상의 method를 사용하게될 확률이 높다. 이 라이브러리에서 사용하고 있는 method의 수가 상당하기 때문에 proguard를 통해 사용하지 않는 함수를 제거하지 않는 이상 65K개를 넘어설 확률
-
Gradle applicationIdSuffix 사용시 AndroidAnnotations 설정
Gradle DSL method not found: 'packageNameSuffix()' 오류 해결에서 오류 해결 방법을 안내하면서 언급했던 applicationIdSuffix를 사용시 유의사항이 있다. applicationId가 debug 모드에서 변경됨에 따라 관련된 부분에서 문제가 일어날 수 있다는 것이다. 나의 경우는 AndroidAnnotations을 함께 사용하는 부분에서 오류를 만났다. AndroidAnnotations에서 applicationId를 기준으로 resource에 접근해서 자동 생성된 class들을 찾지
-
Gradle DSL method not found: 'packageNameSuffix()' 오류 해결
안드로이드에서 빌드시 packageName을 동적으로 변경하기 위해 packageNameSuffix를 사용하는 경우가 있다. 예를들어 배포된 앱과 개발중인 앱을 동시에 사용하기 위해 packageNameSuffix를 사용할 수 있다. 아래의 예시를 보자. android { buildTypes { debug { packageNameSuffix '.debug' versionNameSuffix '-debug' } } } debug 모드에서 빌드할 경우에는 packageName 뒤에 .debug를 붙이도록 설정한 것이다. 이렇게 함으로써
-
ACRA : Please configure 'buildConfigClass' in your ACRA config 오류
Android 6(API 23 : marshmallow) : Apache HTTP 클라이언트 제거 포스트에서 언급했던 것처럼 개발 중인 앱에서 Crash Report를 위해 ACRA를 사용중이다. 아직 4.7.0으로 정식 버전업이 되지는 않았지만 4.7.0 RC1 버전이 maven에 올려져 있어서 적용해 보았다. 사실은 미리 적용할 예정은 없었으나 Android Gradle 빌드 속도 높이기와 관련하여 Gradle을 2.4로 버전업 하면서 release 빌드 시에 다른 오류(setLatestEventInfo 함수가 제거됨)가 나타나
-
안드로이드 Geocoder 사용시 Service not Available 오류
안드로이드에서 특정 지점의 좌표를 주소로 변환하는 것이 필요해서 Geocoder 사용했다. 대략적인 코드는 아래와 같다. static abstract public class GeoCoderTask extends AsyncTask<LatLng, Void, Address[]> { @Override protected Address[] doInBackground(LatLng... arg0) { List<Address> res = new ArrayList<>(); if (arg0.length > 0) { try { Geocoder geoco
-
Android Gradle 빌드 속도 높이기
안드로이드 개발을 하면서 여러가지 불만이 있지만 그중에 가장 맘에 들지않는 것 중 하나가 빌드 속도이다. 프로젝트의 규모에 따라 다르겠지만 xcode와의 빌드 시간을 비교하면 전체 빌드의 시간은 비슷한 것 같으나 수시로 하게되는 빌드는 안드로이드 스튜디오가 훨씬 느리게 느껴진다. 안드로이드 개발시 빌드에 사용되는 Gradle은 많은 유연성을 제공하지만 빌드에 많은 프로세스 비용이 든다는 것이 단점이다. 그래서 빌드 속도를 높일 수 있는 방법을 찾아서 적용해 보았다. 그리고 빌드 시간에 크게 영향을 주는 것 중에는 proguard와
-
안드로이드 테마 정의시 parent를 지정하지 않을 경우 Error: Style Resource definition cycle 발생
이번 포스팅은 정확하지 않은 정보일 확률이 높다. 하지만 비슷한 경우를 만나게되면 임시 해결 방법으론 도움이 될 것 같아 글을 남겨 본다. 이번에 작업하면서 발생한 문제를 해결하는 과정에서 이것저것 해보면서 알게된 부분을 정리해보려고 한다. 일단 문제를 만난 상황부터 이야기하자면 이렇다. 작업 중에 DialogTheme를 정의해서 사용할 일이 있었다. 그래서 다음과 같이 정의해서 사용중이었다. Theme가 무엇인지에 대해서는 http://developer.android.com/intl/ko/guide/topics/ui/themes.
-
Android 6(API 23 : marshmallow) : Apache HTTP 클라이언트 제거
지난 포스팅 Android 6(API 23)의 getColor() deprecated 대응 + getDrawable() deprecated에서 잠깐 언급했던 Apache HTTP 클라이언트 제거에 대해 이야기하고자 한다. 우선 안드로이드에 안내하고 있는 원문은 아래와 같다. 영문 : Apache HTTP Client Removal 한글 : Apache HTTP 클라이언트 제거 한글 문서의 내용은 아래와 같다. Apache HTTP 클라이언트에 대한 지원을 제거합니다. 앱이 이 클라이언트를 사용하고 Android 2.3(API 레벨
-
Android Asynchronous Http Client(android-async-http) 1.4.9 사용시 Proguard를 적용하면 onSuccess 또는 onFailure이 호출되지 않는 문제 해결
안드로이드 앱 개발시 사용하던 android-async-http가 최근 1.4.9 버전으로 버전업되었다. 1.4.8 이하 버전을 사용할 경우 이전에 포스팅한 Android 6(API 23 : marshmallow) : Apache HTTP 클라이언트 제거와 관련된 문제가 있다. 그런데 나는 이 1.4.9 버전을 사용하면서 다른 문제가 생겼다. 빌드에서 오류나 경고는 전혀 나타나지 않지만 URL 호출을 하면 onStart, onProgress까지는 들어오는데 onSuccess, onFailure를 호출해 주지 않았다. 그런데 이 현상
-
안드로이드 TabLayout에서 setupWithViewPager() 사용시 Swipe 후 Tab 클릭시 ViewPager가 변경되지 않는 버그 수정
Android Design Support Library에 있는 TabLayout과 ViewPager를 연동해서 사용하기 위해 setupWithViewPager() 함수를 사용한다. public void setupWithViewPager (ViewPager viewPager) TabLayout와 ViewPager를 연동한다. 이 함수는 아래의 동작을 수행한다. Add a ViewPager.OnPageChangeListener that will forward events to this TabLayout. Populate the TabL
-
안드로이드 ViewPager.setOnPageChangeListener() Deprecated 대응
Android Support Library 22.2.0 이후부터 ViewPager.setOnPageChangeListener() 함수가 Deprecated 되었다. 안드로이드는 무슨 Deprecated가 이렇게 빈번한지... 하지만 이번 변경은 옳은 결정이라고 생각한다. 그냥 Deprecated된 것이 아니라 대체할 수 있는 함수가 함께 추가되었다(더 유연한). ViewPager.setOnPageChangeListener() - Deprecated public void setOnPageChangeListener (ViewPager.
-
AutoCompleteAdapter(ArrayAdapter with Filterable) 사용시 비주기적 오류 발생 해결
AppCompatAutoCompleteTextView를 사용하고자 할때 필요한 것이 데이터를 넘겨주는 Adapter이다. 단, 이 Adepter는 extends ListAdapter & Filterable 가 적용되어야 한다. 그래서 보통은 public class StringAutoCompleteAdapter extends ArrayAdapter<String> implements Filterable 형태의 구현을 많이 사용한다. 그리고 대부분의 경우에 AutoCompleteTextView를 사용하는 이유는 검색어 자동완성 등에 사용
-
PHP의 DateTime을 Java (Android)로 전달하기
안드로이드 앱을 개발하게되면 많은 경우에 서버와의 데이터 연결이 필요하다. 대부분의 데이터 타입은 이 과정에서 큰 문제를 일으키지 않는다(데이터 타입만 명확히 한다면). 하지만 DateTime은 조금 까다로울 수 있다. 프로그램에서 시간은 TimeZone을 가지고 있기 때문에 이 부분을 명확히 하지 않으면 의도치 않은 시간으로 표시된다. 게다가 형식이 맞지 않는다면 제대로 전달되지 않을 수도 있다. 네이버 D2에 있는 Java의 날짜와 시간 API를 보면 Java에서의 Date 처리가 불편하다는 얘기가 있다. 이번 작업에서는 서버는
-
안드로이드에서 구글맵 사용시 맵의 보여지는 영역의 좌표를 원하는 pixel만큼 제외하고 가져오기
이 글의 제목이 참 길고 어렵다. 나름대로 정하긴 했지만 어떻게 해야 내용을 설명할 수 있을지 잘 모르겠기에 그냥 필요한 상황을 차례로 적어보려 한다. 안드로이드에서 구글맵을 사용하면서 현재 맵에서 보여지는 영역의 좌표를 얻고 싶을 때가 있다. 중심 좌표와 확대 비율은 center와 zoom을 통해 쉽게 구할 수 있다. 하지만 필요한 것은 보여지는 영역을 모두 포함하는 좌표들이다. 이 좌표들은 대부분 보여지는 화면 내부에 해당하는 데이터를 query 하기 위해서 사용될 것이다. 다른 경우도 당연히 있을 수 있고... 위의 목적대로
-
AsyncTask의 생성을 UIThread에서 하지 않으면 발생하는 문제 해결
최근에 안드로이드의 앱 성능 개선에 관련하여 여러가지 자료를 확인중이다. 대표적인 것들이 memory leak에 관련된 문제와 thread 사용에 대한 것들이 있다. 오늘 하고자 하는 얘기는 이 thread 관련된 정보를 조사하다가 알게된 부분을 공유하고자 한다. 이 내용의 출처는 여기다. AsyncTask가 UI 스레드가 아닌 곳에서 처음으로 호출된다면 아래와 같은 에러스택이 발생할 수 있다고 한다. 이건 또 무슨 말도 안되는 소린가? 정말 안드로이드는 말도 안되는 이상한 현상들이 너무나도 많다. 하지만 위에 안내한 출처에서 명확
-
안드로이드에서 findViewById 사용시 Generics을 이용해 Type Casting 없애기
안드로이드 작업을 하다보면 findViewById를 아주 빈번하게 사용하게 된다. 이 작업이 생각보다 귀찮다보니 "butterknife"나 "androidannotations" 같은 라이브러리를 사용하게 된다.(당연히 그 함수를 사용이 귀찮다는 이유만은 아니지만) 아래의 방법은 저런 라이브러리를 사용할 때만큼 여러가지 일을 할 수는 없지만 findViewById를 사용함에 가장 귀찮은 작업인 View Type Casting을 하지 않아도 된다. 우린 일반적으로 아래와 같은 방식으로 함수를 사용한다. TextView textView
-
안드로이드 스튜디오에서 WIFI로 Run/Install/Debug 하기
이제 안드로이드 개발을 시작한지 6개월 가량 된 것 같다. 나이 주 개발 영역은 웹이다. 프론드/백엔드, 서버 등등 웹에 관련된 일을 주로하며 예전엔 아이폰 개발도 일부 했었다. 하지만 회사 업무로 인해 안드로이드를 시작하게 되었고 6개월이나 했음에도 아직 초보를 벗어나지 못한 것 같다. 불필요한 사설이 길었지만 6개월간 왜 불편함을 그냥 당연하게 생각하고 작업을 했는지 안타깝다. 어제는 불현듯 책생 위에 널브러져 케이블들을 보며 이걸 없앨 수 없나? 라는 생각이 들었다. 내 책상 위에는 아이폰이 3개, 안드로이드 폰이 2개, 충전
-
안드로이드에서 Dialog 사용시 WindowManager$BadTokenException 발생
안드로이드에서는 거의 모든 작업에 context를 사용한다. 그런데 이 context는 크게 application contet와 activity context가 있다. 문제는 사용시에 구분해서 사용하지 않는다는 것이다. 명시적으로 특정 context를 요구하지 않는다. 이로 인해 많은 혼란이 있고 crash도 많이 발생한다. 사실 오류를 줄이려면 가능한한 activity context를 사용하는 것이 좋다.(경험상...) 하지만 안드로이드에서는 가급적 application context를 사용하기를 권장한다. 가장 대표적인 이유는
-
안드로이드 View.isLaidOut / View.post
안드로이드 View는 isLaidOut이라는 함수를 가지고 있다. 단, API 19(KITKAT)부터 사용가능하다. 사실 그 이하의 기기에서도 다른 방법을 통해서 사용가능하다. 아주 간단히. 이 부분은 나중에 다시 설명하겠다. 우선 isLaidOut 함수에 대해 안드로이드 메뉴얼에는 다음과 같이 나와있다. public boolean isLaidOut () Added in API level 19 Returns true if this view has been through at least one layout since it was la
-
안드로이드에서 android.os.NetworkOnMainThreadException을 발생시키지 않고 HTTP Ping 보내기
오늘은 작업을 하던 중간에 서버로 ping을 보내야 하는 작업이 생겼다. 정확하게는 서버에 간단한 값을 전송해서 로그로 쌓기 위한 작업이다. 우선 안드로이드는 main thread에서 network 작업을 할 수 없도록 되어있다. 억지로 하려고하면 android.os.NetworkOnMainThreadException이 발생한다. 간단히 생각해서 handler를 사용하는 방법도 있으나 메인 handler를 사용하면 마찬가지다. 그래서 가장 간단한 방법은 AsyncTask를 사용하는 것이다. 아래는 url을 인자로 받아 http로 접
-
Android 6(API 23)의 getColor() deprecated 대응 + getDrawable() deprecated
얼마전 Android API 23 버전이 공개되었다. 이와함께 support library, design support library도 함께 23 버전으로 버전업 되었다. 이에따라 여러가지 UI들이 추가되어 필요한 부분을 적용해 보고자 gradle을 수정하고 build 하니 getColor 함수가 deprecated 되었다는 warning을 보게되었다. 아... 최근에 안드로이드는 기본 함수들을 너무 많이 바꾼다. 사실 이번 버전업으로 이것뿐아니라 http 관련된 api가 제거 되었다. 이미 이전부터 deprecated 되었었긴하지
-
Android ViewPager를 직접 생성시 android.content.res.Resources$NotFoundException: Unable to find resource ID #0xffffffff 오류 발생
일반적으로 ViewPager 사용시 layout xml에서 정의해서 사용한다. 하지만 간혹 필요에 따라 ViewPager을 프로그램으로 생성해서 사용하는 경우 있다. ViewPager viewPager = new ViewPager(this); 그런데 이렇게 사용할 경우 아래와 같은 오류를 만나게 된다. android.content.res.Resources$NotFoundException: Unable to find resource ID #0xffffffff at android.content.res.Resources.getResour
-
안드로이드 tap highlight 레이어로 대체하기
오늘은 지난번 -webkit-tap-highlight-color 사용하기 에서 얘기했던 안드로이드 tap highlight 버그를 회피할 수 있는 방법에 대해 포스팅하고자 한다. 일단 기본적인 아이디어는 이렇다. webkit 브라우저는 기본적으로 tap highlight를 숨길 수 있으므로 tap highlight를 투명하게 변경하고 해당 링크의 위치에 원하는 모양의 레이어를 띄우는 것이다. 여기서 또 다른 문제를 함께 해결해야 하는데, 삼성 갤럭시 계열의 스마트폰에서는 숨기는 것 조차 안된다는 것. 그래서 조금 더 꼼수를 부려야