Error generating final archive: Debug certificate expired on ...

이클립스에서 안드로이드 애플리케이션 빌드 중에 이런 오류 메시지가 나오는 경우가 있다.

Debug certificate가 만료되어서 발생하는 문제인데, Debug certificate는 만들어진 후 365일이 지나면 만료된다. 그러므로 만료된 Debug certificate를 새로 갱신해주면 된다. 방법은 간단하다. debug.keystore 파일을 삭제한 후, 그냥 다시 안드로이드 애플리케이션을 빌드만 하면 된다.

debug.keystore 파일의 위치는 'Window > Preferences > Android > Build'에서 'Default debug keystore' 항목을 참조하면 된다.


WRITTEN BY
정현석
이것저것 끄적끄적....

,

이번 장에서는 바로 이전 과정에서 작성한 두 가지 Layout의 화면 구성을 살펴보고

어떤 Layout이 최적화 되었는지 살펴 보겠다.

우선 화면 분석을 위해서는 Eclipse에서 PlugIn으로 존재하는

Hierarchy View 툴을 사용하면 편리하다.

 

1. Hierarchy View에 대해서

 

Hierarchy View는 화면의 View와 ViewGroup 구성이 어떻게 되어 있는지

아주 상세하게 보여주는 Tool이다.

현재 화면 구성의 상태를 디버깅할 수 있다.

 

우선 Hierarchy View를 어떻게 실행하는지 살펴 보자.

 

1.1 Hierarchy View 환경 설정

 

● Eclipse에서 아래와 같이 1번을 선택해 보자.

 

● 아래의 Hierarchy View가 없는 사람들은  "Other"을 선택하라.

    만일 Hierarchy View가 있는 사람들은 그냥 누르면 끝난다.

 

 ● 아래의 Hierarchy View를 선택하라.

 

 ● 아래의 1번을 누르면 Hierarchy View가 구동이 된다.

 

 

1.2 Hierarchy View 구동

 

● 아래는 이전 강좌에 작성한  LinearLayout의 Sample이다.

    해당 Sample을 일단 실행하여 애뮬을 가동한다.

 

 

● 아래와 같은 화면이 나올 것이다.

    여기서 중요한 것은 방금 실행한 LinearLayout Sample 어플리케이션이

    리스트에 있냐는 것이다.

    아래와 같이 1번이 표시되면 정상이다.

    만일 보이지 않으면 2번을 선택해서 화면을 갱신하도록 하자.

    정상적으로 보이면 아래의 1번을 두번 클릭해 보자.

 

● 아래와 같은 화면이 보인다면 정상적으로 구동된 것이다.

 

 

 

 

2. 화면 구조 분석하기

 

● 일단 이전 강좌에서 작성한 LinearLayout의 화면 구성을 살펴 보자.

    아래는 이전 강좌에서 작성한 소스이다.

 

● Hierarchy View를 살펴 보자.

    아래의 1번을 두번 눌러서 크게 보거나,

    아래의 2번을 눌러 축소하여 볼 수 있다.

 

 

● 아래와 같은 구조를 가질 것이다.

    훌륭하지 않은가? ^^

    우선 아래의 노랑색 부분은 무시하고 나머지만 보도록 하자.

    (안드로이드에서는 기본적으로 노랑색 부분의 기본 Layout을 가진다.

     이에 대해서는 다음에 설명토록 하겠다.)

 

● 자 나머지 부분만을 보자.

    대충 보아도 어떻게 구성되어 있었는지 알수 있지 않겠는가?

 

 

● 이제 이전 강좌에서 작성한 RelativeLayout Sample을 실행해 보도록 하자.

    아래는 이전 작성한 소스이다.

 

● 자 RelativeLayout 의 구조이다.

 

 

● 둘을 같이 놓고 비교해 보자.

 

LinearLayout이 RelativeLayout 보다 Tree 깊이가 더 깊고,

View 개수가 더 많다.

Tree의 깊이가 깊을 수록 내부적으로 해당 화면을 그리기 위해 많은 계산이 들어간다.

이제 LinearLayout이 RelativeLayout보다 좀 비효율 적인 것을 알겠는가?

 

하지만 그렇다고 RelativeLayout만을 사용하라는 것은 아니다.

LinearLayout으로만 가능한 화면 구성도 많이 존재하며,

화면 구성이 복잡할 경우 XML 리소스 자체도 RelativeLayout의 경우

복잡해서 가독성이 많이 떨어진다.

그러므로 적절하게 여러가지 Layout을 섞어서 가용하는 것이 실력인 것이다.

 

 

3. 기본적으로 포함된 Layout

 

위에서 LinearLayout에 대해 분석할때

아래와 같이 노랑색 영역이 기본적으로 포함되어 있었다.

이것은 무엇일까?

 

노랑색 부분을 자세히 보자.

눈에 보이지는 않지만 View 구조에 가장 Root에 해당 하는 View가 존재한다.

그것은 바로 1번과 같이 DecorView라고 부른다.

(DecorView는 FrameLayout을 상속 받은 View이다.)

 

그 다음 2번과 같이 LinearLayout이 존재한다.

 

2번에서 LinearLayout으로 갈리는 이유는 바로 "타이틀 바" 때문이다.

아래의 그림을 보자.

1번과 같이 화면의 Title이 바로 그 것이다.

2번과 같이 해당 View를 클릭하면 타이틀만 미리보기가 표시되는 것을 알 수 있다.

 

그 다음 아래의 5번에 해당하는 것이 바로 사용자가 정의하게 될 기본 ViewGroup이 된다.

 

우리는 바로 FrameLayout 위에 원하는 View를 나열하게 되는 것이다.

 

 

4. Hierarchy View의 기타 기능

 

● View 미리보기

 

위에서 1번과 같이 해당 View를 선택하면 2번처럼 해당 View의 하위 View까지 구성된

미리보기 화면이 출력된다.

또한 두번 클릭하면 별도의 창에서 해당 View의 하위 View까지 구성된 미리보기 화면이 나타난다.

여기저기 View들을 클릭해 보라.

 

● View 상세 속성 보기

 

위에서 1번과 같이 해당 View를 선택하면

해당 View에 대한 상세 속성이 2번의 창에서 나타난다.

예로 3번을 보면 해당 XML 소스에서 설정된 값이 나타난 것을 볼 수 있다.

출처 : http://cafe.daum.net/superdroid/aAfL/21
 


WRITTEN BY
정현석
이것저것 끄적끄적....

,
아이스크림 센드위치 2.4.1_r1 버젼 빌드시 Java Version가지고 Error를 낼 때가 있다.
이때는 http://source.android.com/source/initializing.html 에서 제시하듯이
JDK를 Update하고 반드시 설치된 버젼으로 변경을 해주어야 한다.

$ sudo add-apt-repository "deb http://archive.canonical.com/ lucid partner"
$ sudo apt-get update
$ sudo apt-get install sun-java6-jdk

sudo update-java-alternatives -u java-6-sun

현재 내 우분투에 설치된 java를 보고 싶다면 아래와 같이 하면 된다.

sudo update-java-alternatives -l

그러면 빌드가 잘 된다..

아이스크림 샌드위치 버젼의 webkit에서 제공하는  inlineVideo를 이식해봐야 할텐데...
이게 생각처럼 쉽지가 않구만...  

WRITTEN BY
정현석
이것저것 끄적끄적....

,

Java에서 사용하는 System.out  class의 print 함수들이나 Android의 Log class는 static으로 이루어져 있기 때문에 사용량이 많을수록 성능에 지장을 많이 준다. 

이렇게 불필요한 Log들에 의한 성능저하 유발을 방지하기 위해서 몇가지 방법이 있는데
첫번째는, Log를 찍는 곳에 if()의 결과에 따라서 로그를 찍느냐 마느냐를 결정하는 것이다.
그런데 이게 일일이 if()으로 검사하기에는 너무나 귀찮다. 그래서 일괄적으로 할 수 있는 class를 만들어서 사용하면 성능저하도 개선하고 편리성도 찾을 수 있다. 단, 이것 또한
단점이  존재하는데 재빌드를 해야 한다는것이다. 하지만 단점보다는 장점이 더 크니까 해볼만 하다.

package com.infraware.util;


import android.util.Log;


public class Logger {

private static final boolean enabled = true;

private static String createMessage(String filter, String methodName, String message){

StringBuffer msgBuf = new StringBuffer();

msgBuf.append("[");

msgBuf.append(filter);

msgBuf.append("][");

msgBuf.append(methodName);

msgBuf.append("] ");

msgBuf.append(message);

return msgBuf.toString();

}

public static void error(String fileName, String filter, String methodName, String message){

if(enabled){

Log.e(fileName + ".java", createMessage(filter, methodName, message));

}

}

public static void debug(String fileName,  String filter, String methodName, String message){

if(enabled){

Log.d(fileName + ".java", createMessage(filter, methodName, message));

}

}

public static void info(String fileName,  String filter, String methodName, String message){

if(enabled){

Log.i(fileName + ".java", createMessage(filter, methodName, message));

}

}

public static void verbose(String fileName,  String filter, String methodName, String message){

if(enabled){

Log.v(fileName + ".java", createMessage(filter, methodName, message));

}

}

public static void warning(String fileName,  String filter, String methodName, String message){

if(enabled){

Log.w(fileName + ".java", createMessage(filter, methodName, message));

}

}

}

 
이제 내 프로젝트에서 이렇게 사용해봐야 겠다... ㅠㅠ
KWAC Project에 들어간 불필요한 log들을 좀 다 제거하고 싶은데 쉽지 않네... ㅠㅠ 

WRITTEN BY
정현석
이것저것 끄적끄적....

,
순수 자바 어플리케이션이라면 디버그가 꽤나 쉽지만 JNI를 쓴 앱에서 native쪽에서 죽는 문제를 디버그하려면 일단 눈물 부터 닦고 시작해야 하는 게 안드로이드다. 물론 이전에 쓴 안드로이드 Native단에서 GDB로 디버그하기의 방법으로 gdb로 편하게 디버그 할 수도 있지만, 세상일이 언제나 호락호락하게 이쪽 형편에 맞춰 주는 게 아니라서, 가령 특정 단말에서만 Native에서 죽는데 단말 바이너리가 개발용이 아니라서 gdbserver가 탑재 되어 있지도 않고 탑재 시킬수도 없는 상황이라든가 디버그하다가 오히려 gdbserver가 미쳐서 세그멘테이션 폴트로 계속 죽는다든가 뭐 그런 상황이 언제든지 찾아 올 수 있다.

안드로이드 앱이 native 레이어에서 죽으면 보통 다음과 같은 로그를 뿌리게 된다. 

D/dalvikvm( 3130): GC_CONCURRENT freed 461K, 53% free 2874K/6087K, external 452K/1028K, paused 2ms+1ms
I/DEBUG   ( 2573): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
I/DEBUG   ( 2573): Build fingerprint: 'samsung/SHW-M250K/SHW-M250K:2.3.3/GINGERBREAD/ED12:eng/test-keys'
I/DEBUG   ( 2573): pid: 16568, tid: 16577  >>> com.kwac.widgetmanager <<<
I/DEBUG   ( 2573): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000000
I/DEBUG   ( 2573):  r0 00000000  r1 00000001  r2 002191b8  r3 00000000
I/DEBUG   ( 2573):  r4 81da96bc  r5 81da0ae4  r6 00000000  r7 00000000
I/DEBUG   ( 2573):  r8 00000001  r9 81da0ae4  10 46927e54  fp 000fc788
I/DEBUG   ( 2573):  ip 81da0b34  sp 46b3a7b0  lr fffff5a4  pc 81bbbfa0  cpsr 00000030
I/DEBUG   ( 2573):  d0  3f80000041800000  d1  0000000041800000
I/DEBUG   ( 2573):  d2  0000000000000000  d3  0000000000000000
I/DEBUG   ( 2573):  d4  0000000500000000  d5  41d397c7f2000000
I/DEBUG   ( 2573):  d6  408f400000000000  d7  42732239425fd0e1
I/DEBUG   ( 2573):  d8  0000000000000000  d9  0000000000000000
I/DEBUG   ( 2573):  d10 0000000000000000  d11 0000000000000000
I/DEBUG   ( 2573):  d12 0000000000000000  d13 0000000000000000
I/DEBUG   ( 2573):  d14 0000000000000000  d15 0000000000000000
I/DEBUG   ( 2573):  d16 0000000000000001  d17 3ff0000000000000
I/DEBUG   ( 2573):  d18 3ff0000000000000  d19 0000000000000000
I/DEBUG   ( 2573):  d20 0000000000000000  d21 0000000000000000
I/DEBUG   ( 2573):  d22 3ff0000000000000  d23 0000000000000000
I/DEBUG   ( 2573):  d24 3ff0000000000000  d25 0000000000000000
I/DEBUG   ( 2573):  d26 0000000000000000  d27 0000000000000000
I/DEBUG   ( 2573):  d28 0002aaa80002aaa8  d29 0002aaa80002aaa8
I/DEBUG   ( 2573):  d30 0001000000010000  d31 0001000000010000
I/DEBUG   ( 2573):  scr 60000010
I/DEBUG   ( 2573): 
I/DEBUG   ( 2573):          #00  pc 003bbfa0  /data/data/com.kwac.widgetmanager/lib/libwacrt.so
I/DEBUG   ( 2573):          #01  pc 002358f2  /data/data/com.kwac.widgetmanager/lib/libwacrt.so
I/DEBUG   ( 2573):          #02  pc 0023596a  /data/data/com.kwac.widgetmanager/lib/libwacrt.so
I/DEBUG   ( 2573):          #03  pc 0029ae72  /data/data/com.kwac.widgetmanager/lib/libwacrt.so
I/DEBUG   ( 2573):          #04  pc 002ac342  /data/data/com.kwac.widgetmanager/lib/libwacrt.so
I/DEBUG   ( 2573):          #05  pc 0016a0c4  /data/data/com.kwac.widgetmanager/lib/libwacrt.so
I/DEBUG   ( 2573):          #06  pc 0016db78  /data/data/com.kwac.widgetmanager/lib/libwacrt.so
I/DEBUG   ( 2573):          #07  pc 00250044  /data/data/com.kwac.widgetmanager/lib/libwacrt.so
I/DEBUG   ( 2573):          #08  pc 0025045a  /data/data/com.kwac.widgetmanager/lib/libwacrt.so
I/DEBUG   ( 2573):          #09  pc 002508fc  /data/data/com.kwac.widgetmanager/lib/libwacrt.so
I/DEBUG   ( 2573):          #10  pc 00250bfe  /data/data/com.kwac.widgetmanager/lib/libwacrt.so
I/DEBUG   ( 2573):          #11  pc 00242808  /data/data/com.kwac.widgetmanager/lib/libwacrt.so
I/DEBUG   ( 2573):          #12  pc 00157b8a  /data/data/com.kwac.widgetmanager/lib/libwacrt.so
I/DEBUG   ( 2573):          #13  pc 00157bc4  /data/data/com.kwac.widgetmanager/lib/libwacrt.so
I/DEBUG   ( 2573):          #14  pc 0014fada  /data/data/com.kwac.widgetmanager/lib/libwacrt.so
I/DEBUG   ( 2573):          #15  pc 00151a48  /data/data/com.kwac.widgetmanager/lib/libwacrt.so
I/DEBUG   ( 2573):          #16  pc 00151c32  /data/data/com.kwac.widgetmanager/lib/libwacrt.so
I/DEBUG   ( 2573):          #17  pc 00151c56  /data/data/com.kwac.widgetmanager/lib/libwacrt.so
I/DEBUG   ( 2573):          #18  pc 00151fde  /data/data/com.kwac.widgetmanager/lib/libwacrt.so
I/DEBUG   ( 2573):          #19  pc 002edda8  /data/data/com.kwac.widgetmanager/lib/libwacrt.so
I/DEBUG   ( 2573):          #20  pc 0015159e  /data/data/com.kwac.widgetmanager/lib/libwacrt.so
I/DEBUG   ( 2573):          #21  pc 002ef050  /data/data/com.kwac.widgetmanager/lib/libwacrt.so
I/DEBUG   ( 2573):          #22  pc 00158c54  /data/data/com.kwac.widgetmanager/lib/libwacrt.so
I/DEBUG   ( 2573):          #23  pc 001589ac  /data/data/com.kwac.widgetmanager/lib/libwacrt.so
I/DEBUG   ( 2573):          #24  pc 002ede0c  /data/data/com.kwac.widgetmanager/lib/libwacrt.so
I/DEBUG   ( 2573):          #25  pc 0014fb4a  /data/data/com.kwac.widgetmanager/lib/libwacrt.so
I/DEBUG   ( 2573):          #26  pc 00151864  /data/data/com.kwac.widgetmanager/lib/libwacrt.so
I/DEBUG   ( 2573):          #27  pc 00249380 /data/data/com.kwac.widgetmanager/lib/libwacrt.so
I/DEBUG   ( 2573):          #28  pc 00017eb4  /system/lib/libdvm.so
I/DEBUG   ( 2573):          #29  pc 00049ae4  /system/lib/libdvm.so
I/DEBUG   ( 2573):          #30  pc 0001d0c8  /system/lib/libdvm.so
I/DEBUG   ( 2573):          #31  pc 00022398  /system/lib/libdvm.so
I/DEBUG   ( 2573): 
I/DEBUG   ( 2573): code around pc:
I/DEBUG   ( 2573): 81bbbf80 62637022 1c58e00a 0063eb00 ff9cf7ff 
I/DEBUG   ( 2573): 81bbbf90 69e26a63 f8421c59 62617023 e018f8df 
I/DEBUG   ( 2573): 81bbbfa0 f8556831 6019300e 81f0e8bd 0014a6a7 
I/DEBUG   ( 2573): 81bbbfb0 001e4bb4 001ed780 fffff5a4 001ed748 
I/DEBUG   ( 2573): 81bbbfc0 bf004770 4b0bb510 46047a02 b10a447b 
I/DEBUG   ( 2573): 
I/DEBUG   ( 2573): code around lr:
I/DEBUG   ( 2573): fffff584 ffffffff ffffffff ffffffff ffffffff 
I/DEBUG   ( 2573): fffff594 ffffffff ffffffff ffffffff ffffffff 
I/DEBUG   ( 2573): fffff5a4 ffffffff ffffffff ffffffff ffffffff 
I/DEBUG   ( 2573): fffff5b4 ffffffff ffffffff ffffffff ffffffff 
I/DEBUG   ( 2573): fffff5c4 ffffffff ffffffff ffffffff ffffffff 
I/DEBUG   ( 2573): 
I/DEBUG   ( 2573): stack:
I/DEBUG   ( 2573):     46b3a770  46927e54  
I/DEBUG   ( 2573):     46b3a774  afd14173  /system/lib/libc.so
I/DEBUG   ( 2573):     46b3a778  81da96bc  
I/DEBUG   ( 2573):     46b3a77c  00000001  
I/DEBUG   ( 2573):     46b3a780  002191b8  
I/DEBUG   ( 2573):     46b3a784  00000000  
I/DEBUG   ( 2573):     46b3a788  00000001  
I/DEBUG   ( 2573):     46b3a78c  afd14789  /system/lib/libc.so
I/DEBUG   ( 2573):     46b3a790  81da96bc  
I/DEBUG   ( 2573):     46b3a794  81c3f393  /data/data/com.kwac.widgetmanager/lib/libwacrt.so
I/DEBUG   ( 2573):     46b3a798  81da96bc  
I/DEBUG   ( 2573):     46b3a79c  81bbbee9  /data/data/com.kwac.widgetmanager/lib/libwacrt.so
I/DEBUG   ( 2573):     46b3a7a0  81da96bc  
I/DEBUG   ( 2573):     46b3a7a4  81da0ae4  
I/DEBUG   ( 2573):     46b3a7a8  df002777  
I/DEBUG   ( 2573):     46b3a7ac  e3a070ad  
I/DEBUG   ( 2573): #00 46b3a7b0  46b3a7e0  
I/DEBUG   ( 2573):     46b3a7b4  00000000  
I/DEBUG   ( 2573):     46b3a7b8  001b07f8  
I/DEBUG   ( 2573):     46b3a7bc  00000000  
I/DEBUG   ( 2573):     46b3a7c0  00000001  
I/DEBUG   ( 2573):     46b3a7c4  81a358f7  /data/data/com.kwac.widgetmanager/lib/libwacrt.so
I/DEBUG   ( 2573): #01 46b3a7c8  46b3a7e0  
I/DEBUG   ( 2573):     46b3a7cc  0019ff68  
I/DEBUG   ( 2573):     46b3a7d0  001b07f8  
I/DEBUG   ( 2573):     46b3a7d4  00000000  
I/DEBUG   ( 2573):     46b3a7d8  00000001  
I/DEBUG   ( 2573):     46b3a7dc  81a3596f  /data/data/com.kwac.widgetmanager/lib/libwacrt.so

위의 콜 스택을 보면 JNI로 호출 된 libwacrt 라이브러리 내에서 뭔가 열심히 일하다 죽었다는 것을 알 수 있지만 심볼 테이블이 나오지 않기 때문에 실제 어떤 함수를 호출하다가 죽었는지는 표시되지 않는다. 그러나 strip 되지 않은 라이브러리를 objdump 시킨 후 스택 트레이스에 찍힌 PC 값을 기반으로 뭘 하다 죽었는지를 알아 낼 수 있다는 게 이 글의 핵심이다. 

방법은 간단하다. 안드로이드 소스나 NDK에 포함된 objdump를 사용하는 것으로,  objdump 파일은 (리눅스의 경우) prebuilt/linux-x86/arm-eabi-[버전]/bin/ 내에 있다.

$ arm-eabi-objdump -dR libwacrt.so > libwacrt.asm

위와 같이 실행하면 libwacrt.asm 파일이 만들어지게 되며 asm 파일을 열어서 스택 트레이스에 찍힌 주소를 검색해 보면 손쉽게 어디서 죽었는지 확인할 수 있다.

00249348 <_ZN7androidL12DestroyFrameEP7_JNIEnvP8_jobject>:
  249348: e92d 41f0  stmdb sp!, {r4, r5, r6, r7, r8, lr}
  24934c: 4c19       ldr r4, [pc, #100] (2493b4 <_ZN7androidL12DestroyFrameEP7_JNIEnvP8_jobject+0x6c>)
  24934e: 460e       mov r6, r1
  249350: 4605       mov r5, r0
  249352: 447c       add r4, pc
  249354: 68e2       ldr r2, [r4, #12]
  249356: f7ff f895  bl 248484 <_ZN7_JNIEnv11GetIntFieldEP8_jobjectP9_jfieldID>
  24935a: 4607       mov r7, r0
  24935c: f71f fb34  bl 1689c8 <_ZNK7WebCore5Frame4viewEv>
  249360: 4604       mov r4, r0
  249362: 6840       ldr r0, [r0, #4]
  249364: 1c43       adds r3, r0, #1
  249366: 4638       mov r0, r7
  249368: 6063       str r3, [r4, #4]
  24936a: f71f fb27  bl 1689bc <_ZNK7WebCore5Frame6loaderEv>
  24936e: 4680       mov r8, r0
  249370: 4638       mov r0, r7
  249372: f71f fbe3  bl 168b3c <_ZNK7WebCore5Frame4pageEv>
  249376: 4607       mov r7, r0
  249378: f1b8 0f00  cmp.w r8, #0 ; 0x0
  24937c: d002       beq.n 249384 <_ZN7androidL12DestroyFrameEP7_JNIEnvP8_jobject+0x3c>
  24937e: 4640       mov r0, r8
  249380: f708 fa64  bl 15184c <_ZN7WebCore11FrameLoader16detachFromParentEv>
  249384: b12f       cbz r7, 249392 <_ZN7androidL12DestroyFrameEP7_JNIEnvP8_jobject+0x4a>
  249386: 4638       mov r0, r7
  249388: f727 f80c  bl 1703a4 <_ZN7WebCore4PageD1Ev>
  24938c: 4638       mov r0, r7
  24938e: f6c5 ffcf  bl 10f330 <_ZN3WTF8fastFreeEPv>
  249392: 1d20       adds r0, r4, #4
  249394: f705 f876  bl 14e484 <_ZN3WTF10RefCountedIN7WebCore6WidgetEE5derefEv>
  249398: f8df c01c  ldr.w ip, [pc, #28] ; 2493b8 <_ZN7androidL12DestroyFrameEP7_JNIEnvP8_jobject+0x70>
  24939c: 682a       ldr r2, [r5, #0]
  24939e: 4628       mov r0, r5
  2493a0: 44fc       add ip, pc
  2493a2: 4631       mov r1, r6
  2493a4: 2300       movs r3, #0
  2493a6: f8d2 41b4  ldr.w r4, [r2, #436]
  2493aa: f8dc 200c  ldr.w r2, [ip, #12]
  2493ae: 47a0       blx r4
  2493b0: e8bd 81f0  ldmia.w sp!, {r4, r5, r6, r7, r8, pc}
  2493b4: 0035d40e  .word 0x0035d40e
  2493b8: 0035d3c0  .word 0x0035d3c0

이와 같은 방법으로 유추한 콜 스택은:

....귀찮다 위쪽은 생략...
WebCore::ResourceLoader::cancel()
WebCore::DocumentLoader::stopLoading(DatabasePolicy)
WebCore::FrameLoader::stopAllLoaders(DatabasePolicy)
WebCore::FrameLoader::detachFromParent()
android::DestroyFrame(JNIEnv*)

이 되겠다.

%%P.S. 페북에서 누가 댓글 달아서 알게 됐는데 objdump 대신 addr2line을 써도 된다. 오히려 더 편한가??
$ arm-eabi-addr2line -e libwacrt.so 00249380
[소스 위치 어딘가...]/WebCoreFrameBridge.cpp:1044 


WRITTEN BY
정현석
이것저것 끄적끄적....

,
// 웹페이지 띄우기
Uri uri = Uri.parse("http://www.google.com");
Intent it  = new Intent(Intent.ACTION_VIEW,uri);
startActivity
(it);


// 구글맵 띄우기
Uri uri = Uri.parse("geo:38.899533,-77.036476");
Intent it = new Intent(Intent.Action_VIEW,uri);
startActivity
(it);


// 구글 길찾기 띄우기
Uri uri = Uri.parse("http://maps.google.com/maps?f=d&saddr=출발지주소&daddr=도착지주소&hl=ko");
Intent it = new Intent(Intent.ACTION_VIEW,URI);
startActivity
(it);


// 전화 걸기
Uri uri = Uri.parse("tel:xxxxxx");
Intent it = new Intent(Intent.ACTION_DIAL, uri);  
startActivity
(it);  


Uri uri = Uri.parse("tel.xxxxxx");
Intent it = new Intent(Intent.ACTION_CALL,uri);
// 퍼미션을 잊지 마세요. <uses-permission id="android.permission.CALL_PHONE" />


// SMS/MMS 발송
Intent it = new Intent(Intent.ACTION_VIEW);  
it
.putExtra("sms_body", "The SMS text");  
it
.setType("vnd.android-dir/mms-sms");  
startActivity
(it);  


// SMS 발송
Uri uri = Uri.parse("smsto:0800000123");  
Intent it = new Intent(Intent.ACTION_SENDTO, uri);  
it
.putExtra("sms_body", "The SMS text");  
startActivity
(it);  


// MMS 발송
Uri uri = Uri.parse("content://media/external/images/media/23");  
Intent it = new Intent(Intent.ACTION_SEND);  
it
.putExtra("sms_body", "some text");  
it
.putExtra(Intent.EXTRA_STREAM, uri);  
it
.setType("image/png");  
startActivity
(it);


// 이메일 발송
Uri uri = Uri.parse("mailto:xxx@abc.com");
Intent it = new Intent(Intent.ACTION_SENDTO, uri);
startActivity
(it);


Intent it = new Intent(Intent.ACTION_SEND);  
it
.putExtra(Intent.EXTRA_EMAIL, "me@abc.com");  
it
.putExtra(Intent.EXTRA_TEXT, "The email body text");  
it
.setType("text/plain");  
startActivity
(Intent.createChooser(it, "Choose Email Client"));  


Intent it = new Intent(Intent.ACTION_SEND);    
String[] tos = {"me@abc.com"};    
String[] ccs = {"you@abc.com"};    
it
.putExtra(Intent.EXTRA_EMAIL, tos);    
it
.putExtra(Intent.EXTRA_CC, ccs);    
it
.putExtra(Intent.EXTRA_TEXT, "The email body text");    
it
.putExtra(Intent.EXTRA_SUBJECT, "The email subject text");    
it
.setType("message/rfc822");    
startActivity
(Intent.createChooser(it, "Choose Email Client"));  


// extra 추가하기
Intent it = new Intent(Intent.ACTION_SEND);  
it
.putExtra(Intent.EXTRA_SUBJECT, "The email subject text");  
it
.putExtra(Intent.EXTRA_STREAM, "file:///sdcard/mysong.mp3");  
sendIntent
.setType("audio/mp3");  
startActivity
(Intent.createChooser(it, "Choose Email Client"));


// 미디어파일 플레이 하기
Intent it = new Intent(Intent.ACTION_VIEW);
Uri uri = Uri.parse("file:///sdcard/song.mp3");
it
.setDataAndType(uri, "audio/mp3");
startActivity
(it);


Uri uri = Uri.withAppendedPath(
 
MediaStore.Audio.Media.INTERNAL_CONTENT_URI, "1");  
Intent it = new Intent(Intent.ACTION_VIEW, uri);  
startActivity
(it);  


// 설치 어플 제거
Uri uri = Uri.fromParts("package", strPackageName, null);  
Intent it = new Intent(Intent.ACTION_DELETE, uri);  
startActivity
(it);


// APK파일을 통해 제거하기
Uri uninstallUri = Uri.fromParts("package", "xxx", null);
returnIt
= new Intent(Intent.ACTION_DELETE, uninstallUri);


// APK파일 설치
Uri installUri = Uri.fromParts("package", "xxx", null);
returnIt
= new Intent(Intent.ACTION_PACKAGE_ADDED, installUri);


// 음악 파일 재생
Uri playUri = Uri.parse("file:///sdcard/download/everything.mp3");
returnIt
= new Intent(Intent.ACTION_VIEW, playUri);


// 첨부파일을 추가하여 메일 보내기
Intent it = new Intent(Intent.ACTION_SEND);  
it
.putExtra(Intent.EXTRA_SUBJECT, "The email subject text");  
it
.putExtra(Intent.EXTRA_STREAM, "file:///sdcard/eoe.mp3");  
sendIntent
.setType("audio/mp3");  
startActivity
(Intent.createChooser(it, "Choose Email Client"));


// 마켓에서 어플리케이션 검색
Uri uri = Uri.parse("market://search?q=pname:pkg_name");  
Intent it = new Intent(Intent.ACTION_VIEW, uri);  
startActivity
(it);  
// 패키지명은 어플리케이션의 전체 패키지명을 입력해야 합니다.


// 마켓 어플리케이션 상세 화면
Uri uri = Uri.parse("market://details?id=어플리케이션아이디");  
Intent it = new Intent(Intent.ACTION_VIEW, uri);  
startActivity
(it);
// 아이디의 경우 마켓 퍼블리싱사이트의 어플을 선택후에 URL을 확인해보면 알 수 있습니다.


// 구글 검색
Intent intent = new Intent();
intent
.setAction(Intent.ACTION_WEB_SEARCH);
intent
.putExtra(SearchManager.QUERY,"searchString")
startActivity
(intent);



참고 : http://snipt.net/Martin/tag/android

WRITTEN BY
정현석
이것저것 끄적끄적....

,
ENABLE_SVG:=true
ENABLE_SVG_ANIMATION:=true
https://review.source.android.com/#change,17258

WRITTEN BY
정현석
이것저것 끄적끄적....

,

WRITTEN BY
정현석
이것저것 끄적끄적....

,
http://www.kandroid.org/board/board.php?board=androidsource&command=body&no=72

1) /build/core/main.mk 수정
-ifneq (64,$(findstring 64,$(build_arch))) 
+ifneq (i686,$(findstring i686,$(build_arch)))

2) /external/clearsilver/ 내 Android.mk 수정
-LOCAL_CFLAGS += -m64 

참조URL: http://groups.google.com/group/android-platform/browse_thread/thread/b0bb991131589363

./external/clearsilver/cgi/Android.mk 
./external/clearsilver/java-jni/Android.mk 
./external/clearsilver/util/Android.mk 
./external/clearsilver/cs/Android.mk 
주석처리해야할 라인:
#    LOCAL_CFLAGS += -m64 
#    LOCAL_LDFLAGS += -m64

WRITTEN BY
정현석
이것저것 끄적끄적....

,

Android Command

언어/Android 2010. 12. 14. 10:03
[ADP SIM Unlock]
$adb shell
$su
# echo app.setupwizard.disable=1 > /data/local.prop
#reboot

[일부만 빌드]
$. build/envsetup.sh
$ mmm path/to/build : 지정 경로 빌드
$ make snod : 이미지 생성
 
[Make 명령]
$make update -api : 변경 api 적용
$make sdk : sdk 생성
 
[AVD 및 Emulator 명령]
$./android create avd -n <DeviceName> -t 1~3 : avd 생성
$./android delete avd -n <DeviceName> : avd 삭제
$./android list avds : avd 목록
$./android list targets : avd target 목록
$./emulator -avd <DeviceName> or ./emulator -avd <DeviceName> -ramdisk <file> -system <file> - initdata <file> : emulator 실행
 
[Platform Library Sample Build 명령]
$make -j4 PRODUCT-sample_addon_sdk_addon : platform_library build
 
[ADB 명령]
$adb devices : Devices List 보기
$adb install <path-to-apk> : apk 설치
$adb push <local> <remote> : Device 에 복사
$adb logcat : 디버깅
$adb logcat - b radio : radio 디버깅
$adb -s <DeviceName> logcat : Device 선택 후 디버깅


WRITTEN BY
정현석
이것저것 끄적끄적....

,