2012년 12월 28일 금요일

System popup이 떠 있을 때 Activity가 volume설정 시점을 확인하는 방법

볼륨관련 UI를 가지는 activity인 경우라면 system popup이 떠있는 경우라도 hardware volume key에 의한 볼륨값을 해당 activity의 볼륨UI에 업데이트 해야하는 요구가 있을 수 있다.

이러한 경우에는 다음과 같은 방식을 사용한다.

1. BroadcastReceiver클래스 추가

class MediaVolumeChangeReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            boolean hasWindowFocus = %특정_Activity%.this.hasWindowFocus();

            // 현재 activity의 window에게 focus가 없는 경우의 처리
              //
            // 참고로, 키입력에 의해 이동하는 focus가 아니라 window들 중 f/g에 있는 window가
            // 어떤 것인지를 구분하기위한 focus이다.
            // 즉, 안드로이드 플랫폼에서 띄우는 전원종료와 같은 Dialog가 f/g에 있는 경우에 해당 값은
            // false이고, 해당 activity의 window가 f/g에 있다면 true이다.
            if (hasWindowFocus == false) {
                // TODO: 종료팝업이 떠 있는 경우에 volume UI 업데이트 처리
            }
        }
    }
2. MediaVolumeChangeReceiver mMediaVolChgReceiver;
3. BroadcastReceiver 등록
    getApplicationContext().registerReceiver(mMediaVolChgReceiver, new  IntentFilter("android.media.VOLUME_CHANGED_ACTION"));

4. BroadcastReceiver 등록 해제
    getApplicationContext().unregisterReceiver(mMediaVolChgReceiver);

Activity가 System popup이 떠 있는지 여부를 확인하는 방법

Sub title: How to know there's a showing system popup on an activity?

간단하다.

Activity 클래스의 public boolean hasWindowFocus()를 사용하면 된다.

참고로, 해당 플랫폼 코드는 아래와 같다.


    /**
     * Returns true if this activity's <em>main</em> window currently has window focus.
     * Note that this is not the same as the view itself having focus.
     *
     * @return True if this activity's main window currently has window focus.
     *
     * @see #onWindowAttributesChanged(android.view.WindowManager.LayoutParams)
     */
    public boolean hasWindowFocus() {
        Window w = getWindow();
        if (w != null) {
            View d = w.getDecorView();
            if (d != null) {
                return d.hasWindowFocus();
            }
        }
        return false;
    }


2012년 12월 9일 일요일

adb procrank command

Android에서 가장 정확한 memory usage infomation을 제공한다.

tnkim@tnkim-N53SV:~/git/drawingmemo$ adb shell procrank -h
Usage: procrank [ -W ] [ -v | -r | -p | -u | -h ]
    -v  Sort by VSS.
    -r  Sort by RSS.
    -p  Sort by PSS.
    -u  Sort by USS.
        (Default sort order is PSS.)
    -R  Reverse sort order (default is descending).
    -w  Display statistics for working set only.
    -W  Reset working set of all processes.
    -h  Display this help screen.

중요한 정보는 아래와 같다.
  • USS(Unique Set Size)
    • 프로세스만의 고유한 페이지 수. 즉, 공유되지 않은 프로세스의 private한 메모리 크기이다.
  • PSS(Proportional Set Size)
    • USS + (공유 페이지 / 공유하는 프로세스 수)
    • 즉, 프로세스 고유 메모리 사용량 + 하나의 프로세스가 차지하는 공유 메모리 비율
    • 예. 만약 A프로세스가 6MB 메모리를 사용하고 그 중 2MB가 그 프로세스의 고유 영역(USS)이라면, 나머지 4MB는 공유 메모리이다. 4MB의 공유메모리를 4개의 프로세스가 공유하고 있다면 PSS는 2MB + (4MB/4) = 3MB가 된다.
    • 프로세스별 PSS 수치는 adb shell dumpsys meminfo <processname> 을 통해서도 볼 수 있다.
### start of procrank command example ###
tnkim@tnkim-N53SV:~/git/drawingmemo$ adb shell procrank
  PID      Vss            Rss         Pss          Uss        cmdline
 1296   49828K   47396K   18075K   15048K  system_server
 1357   46140K   39876K   11308K    9244K  com.android.systemui
 2951   41388K   38260K    9937K    7892K  com.android.gallery3d
 4174   34972K   34880K    8019K    6400K  android.process.acore
 1186   36564K   36440K    6267K    3468K  zygote
 1525   32160K   32108K    5957K    4676K  com.android.phone
 1492   31620K   31532K    5460K    4248K  android.process.media
 4246   29156K   29060K    3758K    2536K  com.android.quicksearchbox
 4191   29152K   29080K    3600K    2476K  com.android.keychain
 4158   28684K   28616K    3442K    2372K  com.android.defcontainer
 1188    6896K    6896K    2756K    2400K  /system/bin/mediaserver
...
 4991     116K     116K      67K      64K  /sbin/adbd
 8279     124K     124K      63K      56K  /sbin/adbd
 8006     120K     120K      63K      56K  /sbin/adbd
                          ------   ------  ------
                         280030K  239196K  TOTAL

RAM: 868796K total, 275900K free, 27536K buffers, 194924K cached, 1136K shmem, 14140K slab
### end of procrank command example ###

* 참고 사이트

2012년 12월 5일 수요일

비트맵(Bitmap) 사용 시에 OutOfMemoryError가 발생한다.


체크포인트는 아래와 같다.
  1. 사용하지 않는 Bitmap객체에 대한 recycle() 처리
    1. Activity의 onPause() 또는 onDestroy()에서 member field로 사용 중인 Bitmap객체를 recycle
  2. 대용량 이미지 파일을 Bitmap객체로 decode하고자 한다면 아래와 같이 BitmapFactory의 Options을 활용하여 sampling한다.
    1. 메모리 사용량을 줄이기 위해 decode시에 Bitmap을 1/2크기로 sampling하기      위한 방법이다.
      1. BitmapFactory.Options options = new BitmapFactory.Options();
      2. options.inSampleSize = 2;
      3. bitmap = BitmapFactory.decodeFile(filepath, options);
    2. 자세한 방식은 구글링하자~^_^
  3. 특정 플랫폼 메서드 중에서는 내부적으로 OutOfMemoryError를 소비하는 경우가 있다. 그러한 경우에는 해당 method의 실패여부를 알려주는 return값을 받아서 적절히 처리한다.
    1. 내부적으로 OutOfMemoryError를 소비하는 예제 메서드. android.graphics.Bitmap.compress(Bitmap.java:729)

2012년 11월 19일 월요일

하드웨어 리셋 이후에 저장된 파일이 날아간다.


  • 증상하드웨어 리셋 이후에 저장된 파일이 날아간다.
    • 상세 내용: FileOutputStream을 write후 close해서 DDMS의 File Explorer에 해당 파일이 나타났는데도 하드웨어 리셋을 하면 파일 크기가 0이 되거나 파일이 없어진다.
  • 원인: 파일시스템은 버퍼를 활용하고 있다. 버퍼링된 내용이 물리 파일에 씌여지기 전에 하드웨어 리셋이 되기 때문이다.
  • 해결책: FileOutputStream객체의 getFD()를 통해 전달받는 FileDescriptor객체를 이용하여 sync() 를 호출하여, 물리파일에 씌여지는 시기를 강제화 한다.
  • sync()사용 시의 문제점
    • 전화 중과 같은 상황에 sync가 호출 되면 속도가 느려질 수 있다.
  • 참고 링크

Exception없이 Stack Trace를 출력하는 방법

일반적으로 stack trace를 출력하는 방법은 Exception을 이용하는 것이다.
하지만, 디버깅 중 Exception없이 stack trace를 확인하면 도움이 될 경우가 있다.

이럴 경우 아래 클래스를 이용하면 Exception없이도 stack trace를 출력할 수 있다.


public class StackTrace {

    public static String toStackTraceString() {
        StackTraceElement[] elements = Thread.currentThread().getStackTrace();
        StringBuffer buf = new StringBuffer();
        for (int i = 0; i < elements.length; i++) {
            buf.append(elements[i].toString()).append('\n');
        }
        return buf.toString();
    }
}


2012년 11월 9일 금요일

Using HierarchyViewer

HierarchyViewer는 현재 표현하고 있는 View들의 구조 및 특정 View의 상태(속성)를 확인하는데 도움을 준다.

  • debugging 중에 특정 View의 레퍼런스를 확인하고, 해당 레퍼런스가 어떤 View인지 찾는데 유용하다.
    • Filter by class를 통해 class단위의 Filtering을 제공하고 있다.
    • 현재 Filter by id는 동작하지 않는 듯하다. 따라서 class에 의해 filtering한 view들 중에 특정 id를 찾는것에 의해 쉽게 원하는 view를 찾을 수 있다.
  • filtering에 의해 특정 view를 찾았다면 해당 view의 각종 property를 확인할 수 있다.
    • Property 종류는 아래와 같다.
      • Drawing
      • Events
      • Focus
      • Layout
      • Measurement
      • Miscellaneous
      • Padding
      • Scrolling
      • Text

HierarcheyViewer 캡쳐