이 블로그 검색

레이블이 안드로이드 팁인 게시물을 표시합니다. 모든 게시물 표시
레이블이 안드로이드 팁인 게시물을 표시합니다. 모든 게시물 표시

2011년 8월 29일 월요일

액티비티 Flag 사용법

안드로이드를 개발하다면 액티비티를 통해 화면전환을 하다
뜻하지 않게 많은 동일 액티비티가 생성되어 있음을 확인할 수 있습니다.

이는 사용자 입장에서도 Back 키의 반복작업을 해야 하므로 불편하기도 하거니와  리소스에도 문제가 됩니다.
오늘은 이 문제에 대해 해결하는 방법을 찾아 봤습니다.

우선 XML에서 정의하는 정적인 방식과 코드상에서 정의하는 동적인 방법이 있습니다.

1. AndroidManifest.xml  정의하는 방식

 <activity android:name="ButtonActivity" 
      android:launchMode="singleTask">
  </activity>

launchMode에 플래그를 정의하며 사용가능한 속성은 다음과 같이 4가지만 가능합니다.

  standard: 
  스택중 어느곳에나 위치 가능하며 여러개의 인스턴스가 생성가능 합니다.
  singleTop: 
  스택중 어느곳에나 위치 가능하며 여러개의 인스턴스가 생성가능하고 호출한 activity와 현재
  최상위 activity가(top activity) 동일한 경우 최상위 activity가 재사용 된다(기존 최상위 activity는 pop)
  singleTask: 
  루트 액티비티로만 존재하며 하나의 인스턴스만 생성가능하다(타 task에서 동일 activity 사용불가)
  다른 액티비티 실행시 동일 Task내에서 실행이 가능하다

 singleInstance: 루트 액티비티로만 존재하며 하나의 인스턴스만 생성가능하고 태스크내에 해당
  액티비티 하나만 속할 수 있어 다른 액티비티를 실행시키면 새로운 Task가 생성되어
  (FLAG_ACTIVITY_NEW_TASK와 동일) 그 Task내에 포함된다


2. 코드로 정의하는 방식
  소스코드에서 플래그를 사용하고 싶을때에는 Intent에 addFlags() 또는 setFlags() 메소드를 사용합니다.
1.intent = new Intent(this, 
2.Activity3.class);
3.intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
4.startActivity(intent);

사용할 수 있는 플래그 정보는 다음과 같습니다.

  FLAG_ACTIVITY_NEW_TASK: 
  동일 affinity의 task가 있으면 그곳에 실행되고 아니면 새로운 task를 실행합니다.

  FLAG_ACTIVITY_SINGLE_TOP: 
  상단 singleTop과 같으며, 실행시 재사용 액티비티의 실행은 onPause(), onNewIntent(), onResume()
  순으로 호출 됩니다.
  => [B]를 single top설정: [A][B] 상태에서 [B] 호출시 => [A][재사용된B]
  => [B]를 single top설정: [B][A] 상태에서 [B] 호출시 => [B][A][B]

  FLAG_ACTIVITY_NO_HISTORY:
  해당 액티비티는 재활성화시(back키를 눌러 다시 활성화될때) pop  됩니다.
  => [B]를 no history설정: [A][B][A] 상태에서 back키 사용시 [A]가 pop 되고 [B] 역시 
  no history에 의해 pop => [A]

  FLAG_ACTIVITY_REORDER_TO_FRONT:
  activity 호출시 이미 같은 activity가 task내에 있으면 같은 activity는 pop 시키고 해당 activity가 push 됩니다.
  => [A]를 reorder to front설정: [A][B] 상태에서 [A] 호출시 같은 activity인 [A]가 pop되고 => [B][A]

  FLAG_ACTIVITY_CLEAR_TOP:
  해당 task에 있는 모든 activity를 pop 시키고 해당 activity가 root activity로 task에 push 됩니다.
  => [A]를 clear top설정: [A][B] 상태에서 [A] 호출시 모두 pop되고 => [A]
  단, 해당 플래그는 액티비티를 모두 onDestroy() 시킨 후 새롭게 onCreate() 시키기 때문에 [A]를
  유지하려면 FLAG_ACTIVITY_SINGLE_TOP 플래그와 함께 사용하면 됩니다.


2011년 7월 8일 금요일

SoftReference, WeakReference 개념 정리(객체 GC 관리)

WeakReference 


말그대로, '약한' 참조 이다. '약한' 참조는 해당 객체에 대한 소멸을 막지 않는다. 즉, 어떤 객체에 대한 참조가 WeakReference 밖에 남아있지 않다면 그 객체는 gc(Garbage Collection) 의 대상이 된다. 


예를들어, 객체에서 Bitmap의 Recycle 시점을 잡지 못할 경우(Spanned 같은...) 사용한다.


SoftReference


WeakReference 보다는 약간 강한 참조이다. Soft reference 만 남아있는 객체는 메모리의 요청에 의한 gc 의 대상이 된다. 메모리의 남은 공간이 넉넉하다면 gc되지 않을 것이며, 메모리의 남은 공간이 얼마 없거나 하다면 gc 의 대상이 될 것이다.
확실한건 vm 이 OutOfMemoryError 를 발생시키기 전에는 Soft reference 만 남아있는 객체가 gc의 대상이 된다는 점 정도고, 그 이외에는 vm 의 구현에 따라 다를 수 있다.

어플리케이션 종료하기.

안드로이드 어플리케이션을 사용하다 보면
폰 내부에 메모리를 잡아 먹는 몇몇 어플때문에
속도가 느려지곤한다.
그래서 이 어플리케이션들을 말끔히 종료 시키기 위해
Advanced Task Killer 같은 어플을 써서
메모리를 잡아먹고있는 어플을 강제 종료 시키는 일이 종종 있다.
때문인지 이 어플은 안드로이드 유저에게 필수 어플이 되었는데,
물론 좋은 App가 있기는 하지만 이는 왠만해선 없어야 할 일이다.
만든 어플리케이션들이 종료 했을때
제대로 종료되지 않고 메모리를 먹는다면 사용자들에게 불편을 주기 때문이다.
이런것을 막으려면 우리는 어플리케이션 종료시 말끔하게 메모리에서 아웃 시켜야 한다.
보통 어플리케이션 종료시에 사용하는 메서드는 finish();를 많이 쓴다.
하지만 이건 잘못 오해를 하는 경우가 있다.
finish(); 는 해당 액티비티를 종료하는 메서드 인데
대부분의 개발자들은 이것을 어플리케이션 종료시에 사용하고 있다.

이는 마치 어플리케이션이 종료되는것처럼 보이지만
사실은 어플리케이션을 실행되 있고 해당 엑티비티만 종료되고 App자체는 살아 있다.
종료시엔 finish();가 아닌 System.exit(0); 시스템 메서드를 써주면,
프로그램 자체를 종료 시켜주면서 기기상에 해당 app의 리소스를 모두 반환한다.
어플리케이션 실행 도중엔 finish();를 사용하고 종료시에 시스템 메서드를 사용해보자.
그럼 종료시에 메모리를 잡아먹던 어플리케이션이 정상적으로 종료됨을 알 수 있다.

2011년 7월 7일 목요일

WakeLock 사용법

WakeLock 사용법을 알아 보자 !

화면이 꺼져있을 때 스레드가 계속 실행되게 하거나, 프로그램이 실행되는 동안 화면을 계속 켜놓거나, 프로그램이 실행되는 동안 키보드 back light를 켜놓기 위해서 WakeLock을 이용한다.



< -- CODE -- >
PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
wakeLock = powerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK, "MyLock");
wakeLock.setReferenceCounted(레퍼런스 참조 카운트 할것이나 ? 보통 아니오);
wakeLock.acquire(타임아웃설정);


... wakeLock을 통해 살아있을 동안의 동작들 ...

if (wakeLock != null) {
   wakeLock.release();
   wakeLock = null;
}

2011년 6월 30일 목요일

초성검색 알고리즘

/**
* 초성 검색 알고리즘을 위한 클래스 이다.
* @author roter
*
*/
public class SoundSearcher
{
private static final char HANGUL_BEGIN_UNICODE = 44032; // 가
private static final char HANGUL_LAST_UNICODE = 55203; // 힣
private static final char HANGUL_BASE_UNIT = 588;//각자음 마다 가지는 글자수
//자음
private static final char[] INITIAL_SOUND = { 'ㄱ', 'ㄲ', 'ㄴ', 'ㄷ', 'ㄸ', 'ㄹ', 'ㅁ', 'ㅂ', 'ㅃ', 'ㅅ', 'ㅆ', 'ㅇ', 'ㅈ', 'ㅉ', 'ㅊ', 'ㅋ', 'ㅌ', 'ㅍ', 'ㅎ' };


/**
* 해당 문자가 INITIAL_SOUND인지 검사.
* @param searchar
* @return
*/
private static boolean isInitialSound(char searchar){
for(char c:INITIAL_SOUND){
if(c == searchar){
return true;
}
}
return false;
}

/**
* 해당 문자의 자음을 얻는다.
*
* @param c 검사할 문자
* @return
*/
private static char getInitialSound(char c) {
int hanBegin = (c - HANGUL_BEGIN_UNICODE);
int index = hanBegin / HANGUL_BASE_UNIT;
return INITIAL_SOUND[index];
}

/**
* 해당 문자가 한글인지 검사
* @param c 문자 하나
* @return
*/
private static boolean isHangul(char c) {
return HANGUL_BEGIN_UNICODE <= c && c <= HANGUL_LAST_UNICODE;
}

/**
* 생성자.
*/
public SoundSearcher() { }

/** * 검색을 한다. 초성 검색 완벽 지원함.
* @param value : 검색 대상 ex> 초성검색합니다
* @param search : 검색어 ex> ㅅ검ㅅ합ㄴ
* @return 매칭 되는거 찾으면 true 못찾으면 false. */
public static boolean matchString(String value, String search){
int t = 0;
int seof = value.length() - search.length();
int slen = search.length();
if(seof < 0)
return false; //검색어가 더 길면 false를 리턴한다.
for(int i = 0;i <= seof;i++){
t = 0;
while(t < slen){
if(isInitialSound(search.charAt(t))==true && isHangul(value.charAt(i+t))){
//만약 현재 char이 초성이고 value가 한글이면
if(getInitialSound(value.charAt(i+t))==search.charAt(t))
//각각의 초성끼리 같은지 비교한다
t++;
else
break;
} else {
//char이 초성이 아니라면
if(value.charAt(i+t)==search.charAt(t))
//그냥 같은지 비교한다.
t++;
else
break;
}
}
if(t == slen)
return true; //모두 일치한 결과를 찾으면 true를 리턴한다.
}
return false; //일치하는 것을 찾지 못했으면 false를 리턴한다.
}
}


해당 소스 그냥 긁어다가 쓰시면 돼요 ^^

사용법은 평범합니다

SoundSearcher.matchString("검색할대상","검색어");
ex)
SoundSearcher.matchString("안녕하세요","ㅇㄴ하"); //true
SoundSearcher.matchString("반갑습니다","ㅂㄱ습ㄴ"); //true
SoundSearcher.matchString("안녕히가세요","ㅇㄴㅎㅎ"); //false

TRUE가 리턴 되면 찾은 거에요~~

어플 강제 종료시키기

현재 어플에서 back 키를 눌러 종료되도록 구현하고 있습니다.

moveTaskToBack(true); 1번
finish(); 2번
android.os.Process.killProcess(android.os.Process.myPid()); 3번

3가지를 다 사용한 이유는 완전한 프로세스 종료를 원했기 때문입니다.

성능이 좋은 폰일경우는 아주 아주 안보이는 문제지만, 에뮬상에서는 자주 보이는 ANR 에러가 뜨는데

잠재적인 오류를 가진 내용이기 때문에 한번 테스트를 해봤습니다.

처음에는 Thread에 대한 문제로 생각하고 접근했지만, Thread 종료에 대한 문제는 아니었습니다.

Thrad.setDaemon(true)로 하더라도 문제가 있다는 글을 읽었습니다만, 다행히도 이부분 문제는 아닌듯 합니다.

다만 위 3가지의 조합문제일 것이다라는 가정하에 조합을 해보았습니다.

[결과]
1) 2번 + 3번 = 정상

2) 2번 = 정상

3) 3번 = 정상

4) 1번 + 3번 오류

5) 1번 +2번 +3번 = 오류

6) 1번 + 2 번 = 정상

내 어플에 비밀번호 걸기

 비밀번호 확인
1.Intent intent = new Intent(Main.this, Password.class);
2.intent.putExtra(Password.NEXT_ACTIVITY, "com.android.a.ViewProfile");
3.intent.putExtra(Password.PASSWORD, "1234");
4.intent.putExtra(Password.MODE, Password.MODE_CHECK_PASSWORD);
5.startActivity(intent);
 
비밀번호 변경
1.Intent intent = new Intent(Main.this, Password.class);
2.
3.intent.putExtra(Password.NEXT_ACTIVITY, "com.android.a.ViewProfile");
4.intent.putExtra(Password.PASSWORD, "1234");
5.intent.putExtra(Password.MODE, Password.MODE_CHANGE_PASSWORD);
6.startActivity(intent);
 
변경된 비밀번호 확인
1.Intent intent = getIntent();
2.intent.getStringExtra(Password.RESULT_PASSWORD);
 
 

광고 여러개 넣는 방법

다들 광고는 잘 넣고 계시나요.
다 아시는 내용일수도 있지만.. 혹시 모르시는 분을 위해.. 한번 남겨봅니다.

광고 사용법은 광고사마다 다 다릅니다..
하지만 노출률이 떨어지거나, 광고가 없는경우 광고가 안보이게 된다면 정말 낭패죠..

그래서 여러개의 광고사의 광고를 하나씩 번갈아 가면서.. 보여주면 어떨까? 생각이 들었습니다.
대부분 다 비슷하게 하고 계시고요..


간략히 정리하자면 framelayout 에다가 다 집어넣고.. 광고가 올때 맨 앞으로 보여줄 수 있도록 하면 됩니다.


애드몹과 ad@m의 예를 들어보겠습니다.

먼저 하나의 FrameLayout에 광고를 구겨 넣습니다.

<FrameLayout android:layout_width="fill_parent" android:id="@+id/frameLayout1" android:layout_height="50dip" android:layout_gravity="center_horizontal">

<com.google.ads.AdView
android:id="@+id/AdMobView" android:layout_width="fill_parent"
android:layout_height="wrap_content" ads:adUnitId="your_id"
ads:adSize="BANNER" ads:loadAdOnCreate="true" />

<net.daum.mobilead.MobileAdView
android:id="@+id/AdamView"
android:layout_width="320dip"
android:layout_height="50dip"
android:layout_alignParentBottom="true"
android:layout_gravity="center_horizontal"
android:gravity="bottom|center"/>
</FrameLayout>

그리고 activity에서 불러옵니다.

//adam ad
adAm = (MobileAdView) findViewById(R.id.AdamView);
AdConfig.setClientId("your_id");
AdConfig.setAllowUseOfLocation(true);
AdConfig.setTestDevice(null);

//admob
adMob = (AdView) findViewById(R.id.AdMobView);

그리고 리스너에서 광고가 올때 보여주도록 합니다.

//ad@m의 경우
@Override
public void didDownloadAd_AdListener() {
Log.d("adam", "didDownloadAd_AdListener");
//광고오면 앞으로
adAm.bringToFront();
}
@Override
public void failedDownloadAd_AdListener(int arg0, String arg1) {
Log.d("adam", "failedDownloadAd_AdListener");
//안오면 애드몹을 앞으로
adMob.bringToFront();
}

Admob도 리스너가 있죠... 거기에 광고 왔을때 앞으로 가져오도록 해주시면 되겠습니다.
그리고 리스너에서 광고가 올때 보여주도록 합니다.

new AdListener() {
@Override
public void onReceiveAd(Ad arg0) {
// 애드몹 앞으로
adMob.bringToFront();
}
@Override
public void onPresentScreen(Ad arg0) {
// TODO Auto-generated method stub
}
@Override
public void onLeaveApplication(Ad arg0) {
// TODO Auto-generated method stub
}
@Override
public void onFailedToReceiveAd(Ad arg0, ErrorCode arg1) {
// adam 앞으로
adAm.bringToFront();
}
@Override
public void onDismissScreen(Ad arg0) {
// TODO Auto-generated method stub
}
}

 
모든 광고에 리스너를 다실 필요는 없고.. 메인으로 쓸 광고에만 달아서 컨트롤 잘 하시면 될겁니다.

안드로이드 팁 100가지

1. 이미지와 텍스트가 같이 들어간 버튼 만들기
http://www.androidpub.com/15765
2. 버튼 색깔 바꾸기
http://stackoverflow.com/questions/1521640/standard-android-button-with-a-different-color
3. 전체화면 사용하기 (Status bar, Title bar 숨기기)
http://www.androidpub.com/4710
4. ImageButton의 투명 효과 사용하기
http://joywoni.egloos.com/2847047
5. Android 정리문서
http://sgap.springnote.com/pages/5076381
6. 네이티브 안드로이드 개발 관련 블로그
http://hybridego.net/
7. 안드로이드 개발 각종 예제 소스
http://www.androidpeople.com/2010/01/
8. 메뉴별 이미지 처리
http://stackoverflow.com/questions/2065430/fixed-android-detecting-focus-pressed-color
9. 객체 Style 처리
http://www.anddev.org/viewtopic.php?p=37330
10. Button Highlight
http://www.androidpeople.com/category/android-tutorial/
11. SurfaceView
http://vissel.tistory.com/92
12. android:configChanges
http://www.androidpub.com/52338
13. 전원관리
http://samse.tistory.com/entry/AlarmManager-PowerManager
14. 하드웨어 콘트롤 관련 PDF 문서
http://mikechen.com/classes/2009-11-27%20NTU%20Mobile%20Phone%20Programming%20-%20Mike%20Chen%20-%2010%20-%20Security,%20Camera,%20Audio%20and%20Video.pdf
15. unique device ID 고유값 가져오기
http://developer.android.com/reference/android/telephony/TelephonyManager.html#getDeviceId%28%29
16. 안드로이드 네이티브 라이브러리
http://www.imaso.co.kr/?doc=bbs/gnuboard.php&bo_table=article&wr_id=34284
[다른블로그] http://infodev.tistory.com/322
17. Introduction android
http://yotteum.tistory.com/entry/Introduction-Android
18. 안드로이드 - 버튼 OnClickListener 인터페이스 구현
http://woosa7.tistory.com/entry/%EC%95%88%EB%93%9C%EB%A1%9C%EC%9D%B4%EB%93%9C-%EB%B2%84%ED%8A%BC-OnClickListener-%EC%9D%B8%ED%84%B0%ED%8E%98%EC%9D%B4%EC%8A%A4-%EA%B5%AC%ED%98%84
http://www.cyworld.com/kkjw1801/3222534
19. Android - Change Tab Background
http://escomic.net/218
20. KH5200 드라이버 설치
http://kil.imradriss.co.cc:8000/tc/30
21. DrawableTop 이미지 변경하기
http://www.androidpub.com/10154
22. Layout 사이즈 동적변경
http://www.androidpub.com/40481
http://gall.dcinside.com/list.php?id=accident2&no=1195485
23. Android UI 개발기: XML 안쓰고 UI 코딩하기
http://xrath.com/2009/11/android-ui-%EA%B0%9C%EB%B0%9C%EA%B8%B0-xml-%EC%95%88%EC%93%B0%EA%B3%A0-ui-%EC%BD%94%EB%94%A9%ED%95%98%EA%B8%B0/
24. 전화상태 변화감지 리스너
PhoneStateListener 예제
http://www.kandroid.org/board/board.php?board=AndroidTechQnA&page=124&command=body&no=432
25. 안드로이드 하드웨어관련 자료(통화,폰상태,네트워크,카메라,센서)
http://gtko.springnote.com/pages/5396297
http://developer.android.com/reference/android/content/Intent.html
http://developer.android.com/reference/android/net/ConnectivityManager.html
26. sms 수신해서 요약내용 보여주기
http://www.anddev.org/recognize-react_on_incoming_sms-t295.html
http://flytop.tistory.com/62
27. BroadcastReceiver XML설정하기
http://www.androidpub.com/186727
28. 각종 Management 클래스
http://www.imaso.co.kr/?doc=bbs/gnuboard.php&bo_table=article&page=10&wr_id=34565
29. Dialog 구조 분석
(아이콘,텍스트 위치등)
http://sgap.springnote.com/pages/5235569
30. SMS 수신시 Toast 메시지 출력
http://www.androidpub.com/138352
31. Broadcast Receiver :네트워크상태 체크
http://www.anddev.org/viewtopic.php?p=32088
32. 안드로이드 API기능 설명
http://www.jopenbusiness.com/mediawiki/index.php/Android
33. Actions for BroadcastReceiver
http://www.dearsoft.org/tag/broadcastreceiver/
34. Layout.out.xml 생성되는 문제
http://www.androidpub.com/101585
35. Multi Touch
http://www.mentby.com/naya/multitouch-support-in-android-20.html
http://gist.github.com/324166
36. ScrollView 스크롤 하단으로 내리기
http://www.anddev.org/viewtopic.php?p=36823
37. Timer 만들기
http://developer.android.com/intl/de/resources/articles/timed-ui-updates.html
http://www.developer.com/java/ent/print.php/3589961
http://www.androidpub.com/4374
http://blog.inculab.net/25
38. Logcat 동작안하는 에러 발생시 처리
(Could not create the view: For input string: "")
http://www.mail-archive.com/android-developers@googlegroups.com/msg60683.html
39. SSL 인증서 등록하기
http://www.java2go.net/blog/197?TSSESSION=1202a1a23fa67bae15ce3ab15a5a0cea
http://www.virgo81.net/70
http://crazybob.org/2010/02/android-trusting-ssl-certificates.html
http://www.bouncycastle.org/latest_releases.html
40. Signing By Private Key
http://www.devx.com/wireless/Article/39972/1954
41. 영상 녹화하기
http://www.anddev.org/viewtopic.php?p=24723#24723
42. SurfaceView 의 이해
http://androidhuman.tistory.com/entry/카메라를-이용하자-SurfaceView에-대한-이해
http://androidhuman.tistory.com/entry/카메라를-이용하자-카메라-프리뷰-띄우기
43. 안드로이드 JAVA 소스
http://anddev.tistory.com/77
http://anddev.tistory.com/50
http://anddev.tistory.com/42
44. SSL 인증서 우회하기
http://www.experts-exchange.com/Programming/Languages/Java/Q_23063074.html
http://7bee.j2ee.us/blog/2008/03/28/1206704820000.html
45. JAVA SSL 관련 공식문서
http://java.sun.com/javase/6/docs/technotes/guides/security/jsse/JSSERefGuide.html
http://java.sun.com/javase/6/docs/technotes/guides/security/jsse/JSSERefGuide.html#CreateKeystore
http://java.sun.com/javase/6/docs/technotes/guides/security/jsse/JSSERefGuide.html#CodeExamples
http://java.sun.com/javase/6/docs/technotes/guides/security/jsse/samples/sockets/client/SSLSocketClient.java
46. SSL 인증서 증명에러 해결하기
http://blog.naver.com/PostView.nhn?blogId=fidelis98&logNo=140103425406&redirect=Dlog&widgetTypeCall=true
http://code.google.com/p/android/issues/detail?id=1946
http://developer.android.com/intl/de/reference/javax/net/ssl/TrustManager.html
http://mail-archives.apache.org/mod_mbox/hc-httpclient-users/200906.mbox/
http://www.exampledepot.com/egs/javax.net.ssl/GetCert.html?l=rel
http://www.android-portal.com/2007/12/20/secure-server-socket-with-tlsssl-on-android-fails/
http://www.exampledepot.com/egs/javax.net.ssl/TrustAll.html?
http://blog.keduall.co.kr/lsb76/entry/자바-SSL-접속-오류
해결방법: http://www.exampledepot.com/egs/javax.net.ssl/TrustAll.html
47. 안드로이드 Service 에서 Activity 를 실행하는 방법
http://blog.naver.com/huewu/110084868855
48. 안드로이드 이미지(사진) 불러오기
http://shinluckyarchive.tistory.com/469
http://developer.android.com/reference/android/graphics/BitmapFactory.Options.html
49. SSL 인증키 무조건 우회하기
http://groups.google.com/group/android-developers/browse_thread/thread/62d856cdcfa9f16e
50. 효과음 관련 자료(Creating Sound Effects in Android)
http://www.androidpub.com/257540#4
51. 안드로이드(Android) 분석 스프링노트
http://fanpro.springnote.com/pages/4789459
52. BaseAdapter 활용
http://udroid.blogspot.com/2009/04/customized-list-adapter.html
53. ListView에서 Selector 배경을 특정색으로 변경할려면?
http://kippee.dothost.co.kr/kurt/entry/팁-ListView에서-Selector-배경을-특정색으로-변경할려면
54. Tab Focuse에 따른 아이콘 변경하기
http://www.androidpub.com/155974
55. SoundPool 사용(MediaPlayer 관련)
http://www.droidnova.com/creating-sound-effects-in-android-part-1,570.html
http://www.androidpub.com/257540#1
http://www.androidpub.com/257336
56. MediaPlayer 버퍼 캐쉬 만들어 쓰기
http://blog.pocketjourney.com/2008/04/04/tutorial-custom-media-streaming-for-androids-mediaplayer/
57. Android Tutorial 3: Custom Audio Streaming with MediaPlayer
http://blog.pocketjourney.com/2008/04/04/tutorial-custom-media-streaming-for-androids-mediaplayer/
58. SufaceView , MediaPlayer 만들기
http://groups.google.com/group/android-developers/msg/52618aafc7d82156
http://www.kandroid.org/board/board.php?board=AndroidTechQnA&page=2&sort=hit&command=body&no=312
http://kippee.dothost.co.kr/kurt/entry/팁SufaceView-SufraceHolder-MediaPlayer-MediaPlayerControll를-이용한-동영상화면
59. Get the size of the screen.
http://www.anddev.org/viewtopic.php?p=36355
60. Dialog 의 다른 출력방식
http://code.google.com/p/android/issues/detail?id=6225
61. 안드로이드에서 볼륨조절하기.
1.볼륨 조절 버튼으로 조절 하기.
2.화면에서 SeekBar를 통해서 조절하기
http://drcarter.tistory.com/entry/Android-안드로이드에서-볼륨조절하기
62. AudioTrack 활용하기
http://www.google.com/search?rlz=1C1GGLS_koKR311KR313&sourceid=chrome&ie=UTF-8&q=AudioTrack+start+안드로이드
http://apistudios.com/hosted/marzec/badlogic/wordpress/?p=228
63. Memory leak 방지
올바른 Context 사용
http://samse.tistory.com/tag/Activity%20context
http://developer.android.com/intl/de/resources/articles/avoiding-memory-leaks.html
http://www.androidpub.com/258470
64. Bitmap image resizing source
http://skyswim42.egloos.com/3477279
65. MediaPlayer 재생시 특정시간후 소리가 Closing stereo device 현상
http://www.androidpub.com/387458
66. Android 에서 현재 화면 top 에 있는 activity 알아내기.
http://shadowxx.egloos.com/10489531
67. Custom Media Streaming with MediaPlayer
http://whyandroid.com/android/92-android-tutorial-3-custom-media-streaming-with-mediaplayer.html
68. SDK상에서 MediaMetadataRetriever를 이용한 Video thumbnail 얻는 방법?
http://www.suppul.com/blog/main/202
69. android mediaplayer deadlock
http://www.google.co.kr/search?complete=1&hl=ko&q=android+mediaplayer+deadlock&aq=f&aqi=&aql=&oq=&gs_rfai=
http://code.google.com/p/android/issues/detail?id=959
70. AsyncTask
http://tigerwoods.tistory.com/28
71. MySql, Json, Android 연동
http://www.android-center.com/TB/?P=11871
72. PVMF Return Codes
http://www.netmite.com/android/mydroid/1.5/external/opencore/doc/pvmf_return_codes.pdf
http://www.netmite.com/android/mydroid/1.5/external/opencore/doc/
73. Java에서 동영상 변환
http://naingyo.springnote.com/pages/1606686.xhtml
http://blog.zemzem.kr/121
74. android-jni-examples
http://www.codeweblog.com/change-android-jni-examples/
75. How to take pictures in Android
http://snippets.dzone.com/posts/show/8683
76. JMF 2.1.1 - Supported Formats
http://java.sun.com/javase/technologies/desktop/media/jmf/2.1.1/formats.html
77. Android Camera Preview Filter Using Camera.PreviewCallback.onPrevi ewFrame
http://groups.google.com/group/android-developers/browse_thread/thread/c85e829ab209ceea/3f180a16a4872b58?lnk=gst&q=onpreviewframe#3f180a16a4872b58
http://stackoverflow.com/questions/1893072/getting-frames-from-video-image-in-android
78. How to use WebView & WebViewClient
http://earendil75.egloos.com/2584204
http://nuninaya.tistory.com/536
79. BitmapFactory.decodeByteArray gives pixelated bitmap
http://stackoverflow.com/questions/2183808/android-bitmapfactory-decodebytearray-gives-pixelated-bitmap
80. Android Bitmap Object Resizing Tip
http://blog.naver.com/PostView.nhn?blogId=visualc98&logNo=79874750
81.
82. Byte to File (Image)
http://stackoverflow.com/questions/649154/android-bitmap-save-to-location
http://stackoverflow.com/questions/2183808/android-bitmapfactory-decodebytearray-gives-pixelated-bitmap
http://developer.android.com/intl/de/resources/samples/ApiDemos/src/com/example/android/apis/graphics/CreateBitmap.html
http://developer.android.com/intl/de/reference/android/provider/MediaStore.Images.Media.html
http://www.androidpub.com/233509
83. BITMAP 사이즈 줄이고 늘리기
http://vissel.tistory.com/63
84. byte[]->bitmap변환시, Factory returned null메시지
http://www.androidpub.com/370300
http://code.google.com/p/android/issues/detail?id=823
85. Android Supported Media Formats
http://developer.android.com/intl/de/guide/appendix/media-formats.html
86. Mastering_the_Android_Media_Framework
(MediaPlayer Problems And Solutions 포함)
http://docs.huihoo.com/google/io/2009/Mastering_the_Android_Media_Framework.pdf
87. YUV420 to RGB565 conversion in Android
http://blog.tomgibara.com/post/132956174/yuv420-to-rgb565-conversion-in-android
88. Ffmpeg for android
http://gitorious.org/~olvaffe/ffmpeg/ffmpeg-android
http://zimly.tistory.com/entry/FFMPEG-on-Android
http://slworkthings.wordpress.com/2010/02/23/ffmpeg-and-android-mk/
http://groups.google.com/group/prajnashi
89. H.264 Stream 분석
http://blog.daum.net/_blog/BlogTypeView.do?blogid=0LwKe&articleno=6633262&categoryId=697812&regdt=20100412175346#ajax_history_home
http://blog.naver.com/onlyou_4ever/40048828597
90. Broadcasting video with Android - without writing to local files
http://www.mattakis.com/blog/kisg/20090708/broadcasting-video-with-android-without-writing-to-the-file-system
91. 자바 튜토리얼
http://www.javadom.com/tutorial/
http://www.javadom.com/tutorial/serialize/
http://www.javadom.com/tutorial/serialize/htonl.html
http://www.passncool.com/tt/entry/New-IO-Buffers
92. 자바와 C 사이의 SOCKET 통신 (BYTE로 통신,보너스로 LITTLE ENDIAN까지)
http://shonm.tistory.com/category/JAVA/C와%20JAVA%20의%20SOCKET%20통신%20(LITTLE%20ENDIAN)
93. 자바 1.4의 새로운 입출력, NIO API 1부 - 버퍼와 채널
http://javacan.tistory.com/entry/73
94. 안드로이드 내장 APKs 개발방법(초안)
http://www.kandroid.org/board/board.php?board=androidsource&command=body&no=64
95. byte[] image data in onPreviewFrame can Cause out of memory
http://code.google.com/p/android/issues/detail?id=4360
96. [안드로이드] Bitmap , Byte 간의 변환
http://blog.ehxm.net/91
97. Android PC Remote Control
http://androidpcremotecontrol.googlecode.com/files/image01.pdf
98. How to restart video preview after the surfaceDestroyed()?
http://stackoverflow.com/questions/1073293/android-how-to-restart-video-preview-after-the-surfacedestroyed
99. Google Android Camera Focusing Issue
http://everyjoe.com/technology/google-android-camera-focusing-issue/
100. 안드로이드 소스를 보고 싶으면??
http://androidhuman.tistory.com/232
http://hightin.tistory.com/16
http://mokiya.tistory.com/51

2011년 6월 24일 금요일

메모리 누출 피하기

T-Mobile G1과 같은 안드로이드 애플리케이션들은 Heap 메모리 영역이
16MB 로 제한되어 있습니다. 이 메모리는 핸드폰에는 많은 양의
메모리이지만 개발자가 필요로 하는것에는 크게 못 미칩니다.
이 메모리를 모두 다 사용할 계획이 없다고 하더라도 개발시에는
이 영역을 최소한으로 사용해서 다른 애플리케이션들이 Kill 당하지
않고 운용될 수 있도록 해야 합니다. 안드로이드가 더 많은 애플리케이션을
메모리에 상주시킴으로서 사용자는 애플리케이션간에 더 빠른 전환을
할 수 있습니다. 안드로이드를 개발 할 때에 메모리의 누출현상은 대부분의
경우에 같은 실수때문에 일어납니다.

즉, Context에 오랜시간 지속되는 참조를 하기 때문입니다.

안드로이드에서 Context는 아주 다양한 작업을 담당하는데 대부분은
리소스의 접근과 로드하는데 사용됩니다. 때문에 모든 위젯은 생성자에서
Context변수를 받습니다. 일반적인 안드로이드 애플리케이션의 경우에
Context는 두 종류로 구분됩니다. Activity와 Application이 그것인데
개발자는 보통 Activity를 클래스에 상속받고 Context가 필요한
메서드를 상속합니다. 예를 한번 보겠습니다.

@Override
protected void onCreate(Bundle state) {
  super.onCreate(state);
  
  TextView label = new TextView(this);
  label.setText("Leaks are bad");
  
  setContentView(label);
}

위의 코드는 View가 전체 Activity를 참조하고 있고 따라서 Activity가
포함하는 자료도 참조하고 있습니다. 보통 이 자료는 View의 계층과
모든 리소스를 포함합니다. 따라서 Context를 누출한다면 (여기서
누출이라는 뜻은 Context에 계속 참조를 하기 때문에 Garbage Collector가
정리하는 것을 방지 한다는 뜻입니다.) 많은 양의 메모리를 누출하게 됩니다.
주의 하지 않으면 전체 Activity의 메모리가 누출될 수 있습니다.

스크린의 Orientation(방향 즉, Landscape와 Portrait)이 바뀌게 되면
시스템은 Default 설정에 따라 현재 Activity를 파괴하고 그 상태를
유지하면서 새로운 Activity를 생성합니다. 그렇게 하는 동안 안드로이드는
애플리케이션의 리소스로부터 UI를 다시 로드합니다. 만약에 애플리케이션을
개발 할 때 큰 사이즈의 비트맵을 삽입하는데 Orientation(방향)에 따라
계속 로드하고 싶지 않다면 가장 쉬운 방법은 아래의 코드에서 보이는 바와 같이
static 필드에 넣고 사용하는 것입니다.

코드를 보시죠.

private static Drawable sBackground;
  
@Override
protected void onCreate(Bundle state) {
  super.onCreate(state);
  
  TextView label = new TextView(this);
  label.setText("Leaks are bad");
  
  if (sBackground == null) {
    sBackground = getDrawable(R.drawable.large_bitmap);
  }
  label.setBackgroundDrawable(sBackground);
  
  setContentView(label);
}

위의 코드는 실행속도는 아주 빠르지만 또한 아주 잘못된 코드입니다.
먼저 위의 코드에서 첫번째 Orientation(방향) 전환시에 만들어지는
Activity에서 메모리 누출이 발생합니다. Drawable이 View에 전개되면
View는 Drawable에 콜백함수로 설정됩니다. 즉, Drawable은 TextView에
참조하고 있고 TextView 자신은 Activity(Context)를 참조하고 있으며
Activity는 사실상 모든 것을 참조하고 있습니다. (코드에 따라 다름)

위의 예제는 Context의 메모리 누출의 아주 간단한 사례로 실제 프로젝트에서는
Home Screen's Source Code(프로젝트 내에 unbindDrawables() 메서드 참고)
에서 어떤 식으로 메모리 누출이 일어나는지 확인 할 수 있습니다.
흥미롭게도 Context에 관련한 메모리 누출 사례는 얼마든지 있고 정도에 따라
심각하기도 합니다. 이런 경우는 사용가능 메모리 영역이 비교적 빨리 소진됩니다.

Context 메모리 누출을 피하는 방법으로는 두가지 방법이 있습니다.
가장 확실한 방법은 Context 사용범위를 제한된 범위 안으로 한정하는 방법입니다.
위에서 보여드린 예제 코드에서는 static 참조를 사용했지만 이너클래스(Inner Class)
에서 바깥클래스(Outer Class)를 암묵적으로 참조하는 것이 위험한 것임을 보였습니다.

두번째 방법은 Application Context를 이용하는 것입니다.

이 방법에서 Context는 액티비티가 살아있는 동안은 지속되면서도 Activity의 생명주기
와는 별개의 수명을 갖습니다. 개발시에 오랜시간 살아있어야 할 Context가 필요한
Object가 필요하다면 Application Object를 기억하십시오.
Context.getApplicationContext() 메서드와 Activity.getApplication() 메서드를
통해서 사용할 수 있습니다.

메모리 누출 방지에 대해 요약하자면


  • Context Acitivity에 오랜시간 지속되는 참조를 피할 것 (Acivitity를 참조하는 Object는
    생명주기가 Activity 자체와 같아야 한다.)
  • Context Activity 대신에 Context Application을 사용하는 습관을 가지자
  • Activity 안의 Static 이 아닌 이너클래스(Inner Class)를 되도록 사용하지 말자
    Static 이너 클래스를 사용하고 약한 참조는 Activity 안에 두도록 하자
    이 문제에 대한 해결책은 WeakReference를 사용한 Static 이너 클래스를 이용해
    바깥클래스(Outer Class)를 참조하는 것이다.
  • Garbage Collector는 메모리 누출 방지를 보장하지 않는다.