2015년 2월 20일 금요일

Android ListPreference 항목 동적으로 변경하기

Android app의 settings(preference)를 구성하다보면
ListPreference의 항목들을 xml이 아닌 동적으로 업데이트 해줘야 할 필요가 생겨
이를 정리함.

우선 기본으로 봐야 하는 페이지..
Android Settings Documentation

[ListPreference의 항목을 채우는 방법]
by rochdev

Place preferences.xml in res/xml
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">

    <PreferenceCategory android:title="Some title">     

        <ListPreference android:key="default_category"
            android:title="Dynamic categories" android:summary="Dynamic categories summary"
            android:defaultValue="0" />
    </PreferenceCategory>
</PreferenceScreen>
In your activity that extends PreferenceActivity you do something like this in onCreate().
ListPreference listPreferenceCategory = (ListPreference) findPreference("default_category");
if (listPreferenceCategory != null) {
    ArrayList<Category> categoryList = getCategories();
    CharSequence entries[] = new String[categoryList.size()];
    CharSequence entryValues[] = new String[categoryList.size()];
    int i = 0;
    for (Category category : categoryList) {
        entries[i] = category.getCategoryName();
        entryValues[i] = Integer.toString(i);
        i++;
    }
    listPreferenceCategory.setEntries(entries);
    listPreferenceCategory.setEntryValues(entryValues);
}
shareimprove this answer


[Selected Item 설정]
보통 채우고 말것이 아니라
리스트 중 사용되고 있는 항목이 있다면 default value로 설정할 필요가 있음.
(SetDefaultValue()을 사용하면 삽질하게 된다...)

listSections.setValueIndex(항목의 index);



[Item 선택 시 처리]
그리고 list가 선택될 경우의 처리를 위해서 setOnPreferenceChangeListener 사용

listSections.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
   Log.d(LOG_TAG, "new section id = " + newValue.toString());
}
}

여기서 새롭게 선택된 값은 onPreferenceChange인자로 넘어오는 newValue 이며
이전에 선택된 item의 값은 listSections.getValue(), item title은 listSections.getEntry().

2015년 2월 10일 화요일

Node.js 대충 정리

[참고]
http://nodejs.org/

http://en.wikipedia.org/wiki/Node.js
http://ko.wikipedia.org/wiki/Node.js
http://www.slideshare.net/kazikai/nodejs-29836481 (내용 괜찮음)
http://bcho.tistory.com/885
http://www.nodebeginner.org/index-kr.html
http://helloworld.naver.com/helloworld/textyle/12864
http://nodeqa.com/nodejs_ref/65


[History]
- Node.js는 Ryan Dahl(Joyent사)에 의해 처음 시작. (2009년)
 : Flickr의 file upload 진행창을 보았을 때, 업로드 상태를 알지 못해 서버로 Query를 해야 한다는 점을 고민하다 Node.js를 고안하였다고 함.

- 최초 Node.js 버전은 Linux 기반으로 출시. (2009년)
 : Inangural JSConf EU conference에서 발표 후 국제적인 관심을 끌기 시작함.

- Node.js의 패키지매니저인 npm은 2011년에 처음 소개되었다.

- Microsoft는 Joyent사와 파트너쉽을 맺음 (2011년 6월)
 : Node.js의 Windows버전을 7월에 출시 (2011년 7월)

[특징]
- 구글 크롬 웹브라우저의 자바스크립트 엔진인 V8 기반 TCP library와 HTTP 서버 제공
- Single Thread 기반 Event driven 방식
- Non-Blocking I/O
- CommonJS 모듈 시스템 => http://helloworld.naver.com/helloworld/textyle/12864
- C, C++로 만들어짐.


[기본 module]

. Node.js 는 stable api / unstable api 가 나눠짐
. 각 api 의 level이 있음 : http://nodejs.org/api/documentation.html
. 개발시에 필히 몇레벨인지 확인한후, 사용하는것이 필요


[클러스터]
. 노드는 싱글 스레드로 동작하기 때문에 멀티프로세스의 이점을 얻지 못함.
. I/O에 대한 처리는 이벤트 루프를 통해 좋은 성능을 보여주지만 CPU 계산량이 많은 부분에는 취약한 면이 있음.
. 이를 클러스터 모듈을 통해 해소할 수 있음.


[유용한 확장 모듈들]

[node-supervisor, 스크립트 수정 시 재실행 해주는 확장 모듈]
. 변경된 스크립트를 재실행 하지 않아도 종료 후 다시 실행해 줌.
. 또한 application이 종료되면 무한으로 다시 실행 함.

. 설치
 : npm install –g supervisor
. 사용 방법
 : supervisor xxxx.js

[node-schedule, 스케줄링 확장 모듈]

. Crontab과 같이 스케줄링 관리를 하는 모듈 
. 세가지 스케줄링 방법 제공
 1. new Data로 지정한 날짜와 시간에 작동
 2. RecurrenceRule 함수로 동작할 시간의 규칙 지정
 3. 크론 스타일의 반복 주기 설정

[forever, 노드 애플리케이션 관리 확장 모듈]

. 데몬을 사용해서 node 애플리케이션을 실행하는 것과 같이 실행, 관리를 도움
. cmdline에서 사용하는 명령형 도구 이므로 글로벌로 설치
. 실행중인 프로세스 리스트, 정보 확인 가능, stop/restart 관리 가능
. 어플리 종료되면 자동으로 재실행

. 설치
 1. cmdline에서 사용
  $ [sudo] npm install forever -g
 2. 프로그래밍에서 사용
  $ cd /path/to/your/project
  $ [sudo] npm install forever-monitor

. 주요 명령어
 1. 실행
  $ forever start xxxx.js
 2. 실행 리스트 확인
  $ forever list
 3. 실행 중지 (리스트의 [X] 번호)
  $ forever stop 번호
 4. 재시작
  $ forever restart 번호


[npm]
https://www.npmjs.com/
http://en.wikipedia.org/wiki/Npm_(software)
http://forum.falinux.com/zbxe/index.php?document_srl=572898&mid=lecture_tip

. 아이작 슐레터(Isaac Z. Schlueter)가 만든 노드를 위한 패키지 매니저
. 노드에서 사용되는 모듈들의 설치 및 의존성을 관리해 주는 도구
. Java의 maven 처럼 package.json 파일에 modul간 dependenc에 따라서 의존성이 있는 모듈들을 같이 설치 함.
. 주요 명령어
 - npm list xxxx [-g]
 - npm install xxxx [-g]
 - npm remove xxxx [-g]

- windows에서 설치 후 npm 실행 안될 때
c:\users\아이디\AppData\Roaming\npm 폴더 생성
(win 7 기준이고 에러 발생 시 경로가 나옴)

- proxy 설정
npm config set proxy http://xxxxx:yyyy
npm config set https-proxy http://xxxx:yyyy

- UNABLE_TO_VERIFY_LEAF_SIGNATURE 가 발생할 경우
npm config set strict-ssl false
(왠만하면 인증서 등록해서 true로 다시 변경하는게 좋음)


[socket.io]

http://socket.io/


2015년 2월 5일 목요일

도와주세요 팀장이 됐어요 : 소설로 배우는 프로젝트 관리

도와주세요 팀장이 됐어요 : 소설로 배우는 프로젝트 관리
신승환 저 | 위키북스
http://www.yes24.com/24/Goods/2999953?Acode=101



제목이 좀 별로라 안보다가 도서관 둘러보다 있어서 보게 되었는데 생각보다 괜찮다.

책의 구성이 크게 두챕터로 나눠져 있다.
첫 챕터가 한 프로젝트 팀의 이야기를 담고 있는데 각 상황별로 프로젝트 관리 기법을 풀어서 보여준다. 그리고 다음 챕터에서는 소설에서 나온 프로젝트 관리 기법을 좀더 풀어서 저자의 견해와 다른 참고 자료들로 설명을 하고 있다.

쉽게 읽히고 공감이 가는 부분이 많아서 퇴근할 때 보자마자 바로 다 읽어버린 책이고 책의 양이라 부담이 가지 않고 내용도 괜찮다. 또한 이 책을 보며 톰 드마르코의 '데드라인'이 떠오르기도 했다. 톰 드마르코의 책은 소설을 보여주며 인사이트를 주는 것에 비해 이 책은 실제 상황에서 관리 기법을 콕콕 찍어주고 나중에 정리해주기 때문에 적용하는데 더 도움이 되는 것 같다.

나오는 내용 중에 "관리는 일종의 기술(art)입니다."라는게 가장 인상 깊었고
아래는 책보면서 인상 깊은 내용들을 메모한 것임.

- 양날의 검 '왜?'
 : 도요다에는 왜라는 질문을 다섯번 반복하는 습관이 있다. 이는 근본원인을 찾을 때 사용하는 강력한 방법이다. 대증요법에 머무르지 않고 근본원인을 찾을 수 있다.
하지만 '왜?'에는 비난의 뜻이 쉽게 포함될 수 있으므로 도요다식 문화가 자리잡지 않은 팀이라면 가급적 관계를 악화시키는 '왜'라는 질문은 삼가하는 것이 좋다.

- 시너지 효과와 책임감 나눔이 존재하는 팀
 : 팀은
. 일반적으로 작다. 즉, 다섯 명에서 열 명의 구성원으로 이뤄진다.
. 공동의 목적이나 목표가 있다.
. 일 처리 시 서로 합의 접근 방식이 있다.
. 서로 보완하는 능력이 있다.
. 상호 관련되거나 서로 독립적인 임시 목표가 있다.
. 서로에게 넘겨줄 작업을 약속한다.
 "실천가를 위한 실용주의 프로젝트 관리" 에서

팀원들의 공통의 목표를 향해 나아가기 위해 서로의 능력을 최대한 끌어내는 것이 '시너지 효과'이고 '책임감 나눔'은 팀원들이 가진 역량에 맞도록 전체 일을 작은 조각으로 나누어 팀원에게 책임감을 분배해주는 것임.

- 팀장의 리더십
 : 팀장의 한 약속이 한두 번 지켜져서 두터운 신뢰가 쌓이면 이 팀에는 열정과 신뢰가 넘침. 반면 팀장이 내뱉는 공허한 약속은 팀원들의 사기를 저하시키고 얼마 안되는 똑똑한 팀원을 멀리 떠나 보냄.

- 3 Sight (Foresight, Insight, Hindsight)
 : 예지력, 통창력, 회고력.
  계획이 틀어지더라도 그것은 배움의 시작임. 실패의 원인을 발견하고 새롭게 배우고 계획을 수정하고 이런 경험을 정리하는 것이 필요.

- 정보방 열기
 : 팀원들과 상사에게 항상 정보를 공유할 수 있는 정보방?상황판?이 필요함.
   스크럼 방법론을 사용하면서 느낀건데 직접 손으로 쓰고 붙이고 하는 것이 프로그램을 사용해서 관리하는 것 보다 효과가 더 좋다. 팀원에게나 상사에게나

- 0.5 MM의 문제점
 : 프로젝트 계획에서 쉽게 0.5MM을 계획 수행할 수 있을 것이라고 생각하지만 1. 소프트웨어 일의 범위(작업량)가 정확하기 않다는 것과 2. context switching의 비용이 비싸다는 측면에서 손해다.

- 팀장이 바쁘면 망한다.
 : 일손이 모자랄 때 팀장이 프로그램을 짜야할까? 라는 물음에 정답은 상황마다 다름. 어쩔 수 없이 일손이 모자라 팀장이 프로그램을 작성할 때는 프로그래머로서 임하기 전에 관리자 역할에 충실했는지 스스로에게 물어봐야 함.

- 팀장과 팀원이 충돌할 때
 : 상황에 따라 다르지만
   팀장이 강압적으로 시키면 팀원은 지시를 따르지만 속으로는 자신이 맞다라는 생각과 팀장에 대한 불신이 생길 수 있음. 반대로 팀장이 팀원에게 양보하면 자발적이고 생명력이 넘치는 팀을 위하는 것이고 팀원이 틀려서 실패하더라도 서로가 배우는 상황이 되는 것이고 성공하면 팀원을 지지한 팀장이 되는 것임. 단 실패 시 비난하지 말자.

- 멜빈 콘웨이(Melvin Conway)의 법칙
 : 시스템을 설계하는 조직들은 자신들의 조직 사이에 의사소통 구조(communication structure)를 모방한 형태의 설계를 만들곤 한다.

2015년 1월 18일 일요일

Debugging Android WebView, Chrome

[Chrome 개발자 도구를 사용한 원격 디버깅]
https://developer.chrome.com/devtools/docs/remote-debugging

chrome 개발자 툴을 사용하여 Android WebView를 원격에서 디버깅 가능함.

디버깅을 위해서 전제 조건은
- PC에 Chrome 32 이상 버전이 설치 되어야 함.
- Android 기기가 USB로 연결되어야 하고 인식도 되어야 함. (개발자 옵션의 디버깅 체크)
   (인식을 위해 Android Studio를 실행하는 것도 방법)
- Android Chrome 디버깅의 경우 Android 4.0 이상
- Android WebView를 디버깅 하기 위해서는 Android 4.4 이상

* 자세한 설정은 위 링크 참조

- WebView 디버깅을 위해서는 아래 코드를 앱에 포함해야 함.
WebView debugging must be enabled from within your application. To enable WebView debugging, call the static method setWebContentsDebuggingEnabled on the WebView class.
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
      WebView.setWebContentsDebuggingEnabled(true);
  }
This setting applies to all of the application's WebViews.
Tip: WebView debugging is not affected by the state of the debuggable flag in the application's manifest. If you want to enable WebView debugging only when debuggable istrue, test the flag at runtime.
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
    if (0 != (getApplicationInfo().flags &= ApplicationInfo.FLAG_DEBUGGABLE))
    { WebView.setWebContentsDebuggingEnabled(true); }
  }


[WebView의 console.log 확인]

http://developer.android.com/guide/webapps/debugging.html

Android 2.1 이상에서는 WebChromeClient의 onConsoleMessage()를 구현해서 로그를 직접 출력 하라고 되어 있음. (아래는 API level 8 이상일 경우)


WebView myWebView = (WebView) findViewById(R.id.webview);
myWebView.setWebChromeClient(new WebChromeClient() {
  public boolean onConsoleMessage(ConsoleMessage cm) {
    Log.d("MyApplication", cm.message() + " -- From line "
                         + cm.lineNumber() + " of "
                         + cm.sourceId() );
    return true;
  }
});

하지만 그냥 출력이 되는 경우도 있는 듯..

일단 내가 가진 galaxy s4에서는 Log Message에서 console 을 포함하거나
Log Tag가 chromium 이면 WebView에서 출력하는 console.log를 확인할 수 있음.

I/chromium﹕ [INFO:CONSOLE(78)] "Hello World!!!", source: http://192.168.0.1/wa/ (78)


[Debugging with Chrome DevTools]


Chrome DevTools Overview
: https://developer.chrome.com/devtools/index

* chrome://inspect 창에서 안드로이드 기기가 보이지 않는다면
Android Studio를 실행하고 아래 Android 로그창을 열어봐라.(ADB가 초기화 될것임)

* web 페이지의 cache를 삭제 하기 위해서 별도의 metatag를 사용할 필요 없이 dev tools 설정에서 General > "Disable cache (while DevTools is open)" 을 사용하되 dev tools가 실행되어 보여지는 상태여야 한다.

Remote Debugging
: https://developer.chrome.com/devtools/docs/remote-debugging


크롬 개발자 도구
: http://opentutorials.org/course/580


우리가 몰랐던 크롬 개발자 도구 by 박재성
: http://www.slideshare.net/netil/ss-28588952


[FireFox Developers Edition]
: https://www.mozilla.org/en-US/firefox/developer/

- FireFox 개발자 버전이며 개발자를 위한 다양한 툴이 제공됨
- CSS 수정이 용이(editing)하며 바로 화면에 적용되어 수정내역을 확인할 수 있다
  : 개발자 도구 > Style Editor 에서 수정 및 저장.
  : 하지만 렌더링 결과물이 Chrome, IE와 좀 차이가 나서 후 조정이 필요하다.

2015년 1월 6일 화요일

mobile device에서 touch 시 zoom 방지 하는 방법

젠장.. GB같은 옛날 기기에서는 안된다..
-----------------------------------

보통 web page의 확대/축소를 방지하기 위해서 아래와 같이 viewport를 설정하는 방법을 많이 사용함.

<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" />

하지만 일부 예전 device들 중에서는 제대로 되지 않는 경우가 있음.
이럴 때는 touch를 방지하는 방법으로 가능함.

http://stackoverflow.com/questions/8071603/safari-ipad-1-how-to-disable-zoom-centering-on-double-tap-but-keep-pinch-zoom


6down vote
+100
There's no other way than catching the events you want to prevent, and call preventDefault() on them, as you had already more or less figured out.
Indeed, some particular CSS properties / values may change the global site behavior (fixed width or fixed, for example), but you're not safe from changes to the OS (see fixedhandling change in iOS5), nor do these changes necessarily prevent all behavior (pinch might be off, but not double-tapping).
So, the best way to disable default behavior only for double-tapping is to take advantage of the count of touches iOS provides: if we have only one contact, then we're tapping. Two, this means we're pinching.
The following setup code provides that functionality:
var elm = document.body; // or some selection of the element you want to disable

var catcher = function(evt) {
    if (evt.touches.length < 2)
        evt.preventDefault();
};

elm.addEventListener('touchstart', catcher, true);
Demo on jsFiddle.
Note: the third parameter (true) to addEventListener means that we want to capture events, that is catch them all, even for our descendant children.
share|improve this answer


하지만 이렇게 되면 
전체 화면에서 touch가 먹지 않으므로 touch 필요한 버튼 같은 부분들에서는 문제가 발생그래서 touch가 된 html dom element를 확인하여 touch event를 허용, 취소 여부를 판단하는 코드를 추가함.

touch 필요한 dom element에 대해서는 class='button'와 같이 설정 하였음.

그래서 터치된 element의 class에 button이 포함 되어 있을 경우는 touch event가 전달 되고 그외에는 evt.preventDefault()로 인해서 touch event가 전달되지 않음.


var changedTouch = event.changedTouches[0];
var elem = document.elementFromPoint(changedTouch.clientX, changedTouch.clientY);

if($(elem).attr('class').search("button") != -1){
   return;
}

2014년 12월 11일 목요일

jQuery에서 ajax() 호출 시 response가 항상 똑같은 경우 (ajax GET, PUT method의 caching 방지)

일부 브라우저에서는 jQuery ajax로 GET, PUT method 호출 시
받아온 결과값이 항상 일정하거나 PUT이 제대로 먹히지 않는 경우가 있음.

원인을 몰라 난감하던 차에 아래 사이트 발견

selfesteem님의 [jquery] $.ajax 에서 GET일때 cache가 남는경우...
http://selfesteem.tistory.com/entry/jquery-ajax-%EC%97%90%EC%84%9C-GET%EC%9D%BC%EB%95%8C-cache%EA%B0%80-%EB%82%A8%EB%8A%94%EA%B2%BD%EC%9A%B0

http://stackoverflow.com/questions/367786/prevent-caching-of-ajax-call


위의 사이트를 참조하여
ajax로 GET method 호출 시

cache : false, 를 항상 추가하고

ajax로 PUT method 호출 시

URL + '?' + $.now() 로 해결함.


그리고 이 문제는 Galaxy S2에서 항상 재현된다.


2014년 12월 10일 수요일

jQuery ajax() 사용시 jqXHR의 error code가 0일 경우

jQuery를 사용하여 Ajax를 사용해서 REST API를  잘 호출 하고 있었으나
종종 앱 종료 시 호출되는 Ajax 호출이 error로 처리 되어
서버에서 종료 처리가 되지 않고 앱이 그냥 종료되는 상황이 발생함.

Ajax 호출 코드는 다른 곳에서도 잘 실행되던 거라
종료 처리를 하는 DELETE method가 문제인가 계속 확인을 하던 중
아래 링크들을 확인함.

http://cricri4289.blogspot.kr/2013/10/jquery-ajax-error-code-0.html
http://stackoverflow.com/questions/14313283/jquery-ajax-jqxhr-status-is-always-0


일반적인 경우는 Ajax 호출 후 바로 페이지가 새로고침이 되거나 전환 될 경우
Ajax 호출이 실패하고 error code가 0으로 리턴 될 경우가 있다고 함.
그게 아니라면 실제로 서버 연결이 안되거나 할 경우이고.

암튼 나의 경우는 Ajax 호출 후 바로 앱을 닫아 버려서
미처 Ajax 호출이 완료되지 않은 상태에서 앱이 종료되어 문제가 되었던 경우라서
Ajax 호출이 완료 되어 callback에서 종료 처리를 하고
혹시나 몰라 timeout을 사용해서 종료 처리를 하도록 함.