슬립모드에 들어갈때와, 슬립모드 해제할때에 무언가 동작을 하기 위해서는 2가지 이벤트를 받아야 한다.


android.intent.action.SCREEN_ON

android.intent.action.SCREEN_OFF


이 두가지 이벤트는 안드로이드 정책 변경으로 인해 Manifest에 기술해서는 받을 수 없고, registerReceiver()를 이용하여 동적으로 등록해야만 정상적으로 이벤트를 받을 수 있다.


다음처럼 등록을 하여 사용하였다.


ScreenOnReceiver screenOnReceiver = new ScreenOnReceiver();

IntentFilter filter = new IntentFilter();
filter.addAction("android.intent.action.SCREEN_ON");
filter.addAction("android.intent.action.SCREEN_OFF");
registerReceiver(screenOnReceiver, filter);


class ScreenOnReceiver extends BroadcastReceiver {
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        Log.d("SmartPortal", "ScreenOnReceiver, onReceive:" + action);
        if (action.equals(Intent.ACTION_SCREEN_ON)) {
            ...
        }
        else if (action.equals(Intent.ACTION_SCREEN_OFF)) {

...

        }
    }
}



어플 등록중 구글 플레이스토어에서 정책 위반이라면서 다음과 같은 메일이 왔다.


아래 설명된 문제를 해결한 다음 변경한 업데이트를 제출하시기 바랍니다.

거부 이유: 콘텐츠 정책의 금지 사항 조항 위반

정기 검토 결과 앱에서 YouTube 동영상의 백그라운드 재생을 허용하는 것으로 확인되었으며, 이는 YouTube API 서비스 약관의 다음 부분을 위반하는 것입니다.

'귀하의 API 클라이언트 및 귀하는 사용자 또는 기타 제3자에게 다음 작업을 장려하거나 이를 가능하게 하는 기능을 만들어서는 안 됩니다. (8) YouTube API를 통해 이용하도록 제작된 모든 YouTube의 시청각 콘텐츠의 오디오 또는 동영상 요소를 구분, 분리, 수정하는 작업'


기존에 개발 된 어플을 수정만하고 있던차라 처음에는 full wake lock을 하는 서비스 때문에 문제가 있는거라 생각하여 쓸모없는 서비스라 제거를 하고 다시 시도를 했지만 2번째엔 앱이 삭제되었다고 메일이 왔다. 정책 위반사항은 위의 빨간색으로 표시한 것과 같은 내용이었다.


어플이 실제로는 webview를 통해서 모바일페이지를 보여주는 형태의 껍데기이기 때문에 계속 찾다보니 회사 사이트에서 youtube 사이트로 가는 링크가 있는것을 알게되었고, 거기서 영상을 재생하고 슬립모드로 들어가도 영상이 계속 재생(소리가 계속 재생됨)되는것을 확인하였다.


기본 인터넷 어플은 전혀 그런현상이 없는것을 확인하고 이리저리 알아본 결과 다음과 같이 해결할 수 있었다. webview가 있는 activity의 onPause를 추가한다.


protected void onPause() {
    super.onPause();
    try {
        Class.forName("android.webkit.WebView")
            .getMethod("onPause", (Class[]) null)
            .invoke(webView, (Object[]) null);
    } catch(Exception e) {
        e.printStackTrace();
    }
}


WebView.onPause()도 있으나 이 API는 Android 11에서부터 지원한다.


이제 영상은 정상적으로 pause되나 웹뷰 동작이 정상적이지 않게된다. 그것은 onResume을 호출해줌으로써 해결했다.




2017.1.10 추가

protected void onResume() {
    super.onResume();
    try {
        Class.forName("android.webkit.WebView")
            .getMethod("onResume", (Class[]) null)
            .invoke(webView, (Object[]) null);
    } catch(Exception e) {
        e.printStackTrace();
    }
}






쿼리시 다음을 입력하면 보기 좋게 출력된다.

sqlite> .header on

sqlite> .mode column



- 참조

- http://www.colm.net/open-source/ragel/

- http://www.colm.net/wp-content/uploads/2014/10/ragel-guide-6.9.pdf


- Ragel 사용이 더 좋은 작업

- 문자열 파싱

- 프로그래밍 언어 분석(컴파일러 제작)

- 사용자 입력 검증


- 지원 언어

- C, C++, Obj-C, C#, D, Java, Go, Ruby


- 코드

- Ragel은 유한상태머신(Finite State Machine, FSM)을 구현

- 여러줄 인 경우 "%%{"와 "}%%"로 감싸고, 한줄 인 경우 라인의 앞에 "%%"를 입력한다.

- C언어처럼 한 줄의 마지막에 ";"을 입력한다.

예)

%%{

machine atoi;

...

%%}

%%write init;


- 코드 삽입

- FSM의 이름 삽입

%% machine {FSM 이름};


- Ragel 코드 시작은 main이다.

- ":=" 연산자는 R-Value의 표현식을 나타내는 상태 셋을 생성한다.

%% main := {수식};


- 수식

- 사용자 정의 된 이름 혹은 미리 정의된 이름, 사용자 정의 Action이 올 수 있다.

- Action은 사용자 입력이 수식과 매칭되는 경우 실행할 코드를 넣는 일종의 함수로 각 언어별 실행 코드를 넣는다.

%% action on_word {printf("%n\n", n);}

- 사용자 정의 수식을 정의하려면 "=" 을 사용한다.

%% word = ^space+;


- FSM 초기화 및 시작

- FSM 에서 필요한 상수 선언

%% write data;

- FSM 데이터 초기화

%% write init;

- FSM 실행

- 실제 FSM이 실행 될 위치에 다음과 같이 삽입한다.

%% write exec;


- Action 종류

- Action은 연산자에 따라서 실행하는 방법이 달라진다.

- {수식} > {Action}: Entering Action(FSM state: from the start state)

- 수식에 진입하는 시점에서 Action이 실행된다.

- 예를들어, 문자열을 파싱할 때, 처음 한번만 실행하는 경우

%% action onStart {puts("Start Parsing");}

%% main := alpha+ > onStart;

- {수식} @ {Action}: Finishing Action(FSM state: into a final state)

- 수식의 마지막에 Action이 실행된다.

- 다음은 a-z까지의 소문자가 하나 있을때마다 lower Action이 실행된다.

%% word = ([a-z] @lower)+;

- 다음은 a-z까지의 소문자가 아닌 경우 notLower Action이 실행된다.

%% word = [a-z]+ @notLower;

- {수식} $ {Action}: All Transition Action(FSM state: all state for matched)

- 수식과 매칭될 때마다 Action이 실행된다.

- 다음은 a-z까지의 소문자가 하나 있을때마다 lower Action이 실행된다. (Finishing Action 예제의 변형)

%% word = [a-z]+ $lower;

- {수식} % {Action}: Leaving Action(FSM state: go out of a machine via a final state)

- 수식을 벗어날 때 실행된다.

- 다음은 a-z까지의 소문자가 아닌 경우 lastLower Action이 실행 된 후 notLower Action 실행된다.

%% word = [a-z]+ %lastLower @notLower;

- Action의 순서

>(Entering) $(All) %(Leaving) @(Finishing)


- 주요 연산자

- {수식}+: 1개 이상

- {수식}*: 0개 이상

- {수식}?: 0개 혹은 1개

- ^{수식}: 수식의 반대, ^space 는 공백문자가 아닌 모든 문자를 뜻함.

- ({수식}): 그룹핑, 여러 수식을 하나의 수식으로 처리

- {수식1}|{수식2}: or 연산, 수식1 혹은 수식2와 매칭


- cs(Current State): FSM 상태를 나타내는 변수, 에러, 성공등의 값이 저장.


- 스캐너
- 상태 셋을 생성하는 ":=" 연산자를 사용하여 정의한다.
- 여러가지 패턴 목록을 정의한 후 각 패턴마다 action을 실행할 수 있다.
- main을 정의할 때 스캐너로 정의할 수 있으며, 별도로 정의한 경우 "@{fcall" {스캐너이름}"}" 형태로 실행한다.
- 기본 구조는 다음처럼 스캐너 이름을 정의하고 "|*" 와 "*|" 사이에 패턴과, 패턴 매칭시 실행 될 Action을 정의한다.
- Action을 정의할 때 "=>" 연산자는 생략가능하다.
{스캐너 이름} := |*
{패턴} [{[=>] Action}];
...
*|
- 다음은 영문자와 숫자가 합쳐져 있는 문자열에서 숫자를 검색하는 스캐너이다.
digit_scan := |*
alpha+;
digit+ {puts("digit!");};
*|
- 스캐너는 매칭된 문자열의 시작과 종료를 ts(token start), te(token end)에 저장한다.
- 매칭되기 전의 ts와 te는 같은 값을 가지며, 하나의 패턴이 매칭되면 그 다음 위치를 저장한다.
- 예를들어 90번지에서 100번지까지 패턴이 매칭되었으면 그 다음 패턴 검색시 ts, te의 값은 101이다.
digit_scan := |* ...
digit+ => {char buf[12]; memcpy(buf, ts, te - ts); puts(buf);};
*|


퍼옴: http://www.kaisyu.com/notes/google-android/android-partial-module-build


특정 모듈만 build 하기

  • $ANDROID_HOME/build/envsetup.sh 스크립트를 사용하면 간편하게 특정 module만 build할 수 있다. (envsetup.sh에 대한 더 상세한 내용은여기를 참고하자.)
  • 먼저 shell 상에서 위 스크립트를 현재 환경으로 load 해준다. ($ANDROID_HOME 환경 변수는 Android full source root 경로 값을 저장하고 있는 것으로 미리 정의되어 있어야 한다.)
    $ . $ANDROID_HOME/build/envsetup.sh
  • 자주 사용한다면 그냥 .profile 이나 .bashrc 같은 파일에 추가해두는 것도 좋다.
  • 아무튼, 위 스크립트에서 제공하는 함수들 중 m, mm, mmm 세 가지를 사용하게 된다.
    • m - 현재 경로를 기준으로 소스 트리의 최상위 경로로 이동한 후 make를 실행해준다.
    • mm - 현재 경로를 기준으로 가장 가까운 단위 모듈을 찾아서 그 모듈만 build 해준다.
    • mmm - 파라미터로 주어진 경로들에 대해 단위 모듈 build를 해준다. 마지막에 snod를 추가할 경우 System image 파일까지 새로 생성해준다.
  • 예를 들어보자.
    • Email application package만 새로 build 하고 싶은 경우 다음과 같이 해줄 수 있다.
      $ cd $ANDROID_HOME/packages/apps/Email
      $ mm
    • 혹은 mmm을 사용해서 package build 후 System image까지 새로 생성하는 방법도 있다.
      $ cd $ANDROID_HOME/packages/apps/Email
      $ mmm . snod


출처: http://blog.daum.net/english_100/5


GNU C의 커다란 특성(초보자가 알기 쉽지 않지만) 중 하나는 속성(__attribute__)체계이다. __attribute__는 함수속성(Function attribute) 변수속성(Variable attribute) 그리고 타입속성(Type attribute)로 구분 된다. __attribute__의 표현 방식은 attribute의 앞과 뒤에 각각 두개씩의 아래바(__)를 붙이고 바로 이어 괄호안에 속성 인자를 쓰도록 되어있다.

 

 

1. 함수속성 (Function Atrribute) 

참조 : http://gcc.gnu.org/onlinedocs/gcc-4.6.1/gcc/Function-Attributes.html#Function-Attributes

 

GNU C에서 프로그램에서 불리워질 함수들에 대해 컴파일러로 하여금 더욱 주의하여 최적화하고 검사하도록 선언할 수 있다. __attribute__는 우리가 함수를 선언할 때 특별한 속성을 부여할 수 있다. 이 __atribute__ 다음에는 쌍괄호로 싸여진 속성인자가 따라온다.

우리는 다음의 속성 키워드의 앞뒤에 __을 붙여 사용할 수 있다. 이는 같은 이름으로 정의된 매크로들에 상관없이 헤더파일에서 이 키워드들을 사용할 수 있게 해준다.


alias ("target")

alias 속성은 함수의 선언이 이미 명기된 다른 심볼에 대한 알리아스를 발생하도록 한다. 예를 들어,

void __f() { /* Do something. */ ; }

void f() __attribute__((weak, alias("__f")));

'f'를 '__f'에 대한 약한 알리아스로 정의한다.

 

aligned(alignment)

이 속성은 함수에 대한 최소정렬을 바이트 단위로 명기한다.

함수의 정렬을 감소시키기 위해 이 속성을 사용할 수 없고 단지 증가를 위해서만 사용가능하다. 하지만 함수에 대한 정렬을 명기했을 경우 -falign-functions 옵션의 효력은 사라지게 된다.

aligned 속성에 의한 효과는 링커(linker)에 의해 제한될 수 있다. 많은 시스템에서 함수는 링커가 제공하는 최대 정렬값까지 정렬될 수 있다. (어떤 링커는 최대 정렬값이 매우 매우 매우 작다.) aligned 속성은 변수에도 사용될 수 있다. (Variable Attribute 참조)

 

alloc_size

always_inline

gnu_inline

artifical

bank_switch

flatten

error("message")

warning("message")

 

cdecl

인텔 386 시스템에서 cdecl 속성은 컴파일러로 하여금 함수 인자를 전달하기 위해 사용했던 스택공간을 호출함수가 정리(pop off)할 것으로 가정하게 한다. 이는 -mrtd 스위치 효과를 덮어씌우기 위해 사용될 수 있다.

 

const

constructor

destructor

constructor(priority)

destructor(priority)

deprecated

deprecated(msg)

disinterrupt

dllexport

dllimport

eightbit_data

exception_handler

externelly_visible

far

fast_interrupt

 

fastcall

인텔 396 시스템에서 fastcall 속성은 컴파일러로 하여금 함수의 첫째 인자는 ECX를 통해 두 번째 인자는 EDX를 통해 전달하게 한다. 이어지는 더 많은 인자들은 스택을 통해 전달한다. 스택의 인자값들은 호출된 함수에서 정리(pop off) 한다. 만약 함수에 전달되는 인자수가 가변적이라면 모든 인자들은 스택을 통해 전달된다.

 

thiscall

인텔 386 시스템에서 thiscall 속성은 컴파일러로 하여금 함수의 첫째 인자는 ECX를 통해 전달하게 한다. 이어지는 다른 인자들은 스택을 통해 전달한다. 스택값은 호출된 함수에서 정리(pop off)된다. 전달되는 함수 인자 수가 가변적이면 모든 인자들은 스택을 통해 전달된다. thiscall 속성은 C++ non-static member 함수를 위한 것이다.

 

format( archetype, string-index, first-to-check )

format 속성은 함수가 printf, scant, strftime, strfmon 등과 같은 함수 인자 스타일을 갖음을 명기함으로써 포맷 문자열에 대해 typecheck가 이루어지게 한다. 예를 들어

extern int

my_printf(void *my_object, const char *my_format, ... )

__attribute__((format (printf, 2, 3)));

        

위 선언은 컴파일러로 하여금 my_printf를 호출하기 위해 함수인자인 my_format이 printf 형식의 포맷 문자열로서 모순이 없는지를 체크하게 한다.  

파라메터 archetype은 포맷 문자열을 해석할 방식을 결정하는데 printf, scant, strftime, gnu_printf, gnu_scanf, gnu_strftime, strfmon 중에 하나이어야 한다. 파라메터 string-index는 어떤 함수인자가 포맷 문자열인지를 가리키며 first-to-check는 문자열에 대해 체크해 나갈 첫 함수인자의 번호이다. 한가지 용례로 아래의 test.c 프로그램을 보자.

1:

2: extern void myprint(const char *format, ...) __attribute__((format(print, 1, 2)));

3:

4: void test()

5:{

6:      myprint("%d\n", 4);

7:      myprint("%s\n", 4);

8:      myprint("%s\n", "abc");

9:      myprint("%s %d %d\n", 4, 6);

10:}

$gcc -Wall -c test.c test를 수행하면 다음과 같은 경고가 나타난다.

test.c: In function 'test'

test.c:7: warning: format '%d' expects type 'int', but argument 2 has type 'char *'

test.c:9: warning: format '%s' expects type 'char *', but argument 2 has type 'int'

test.c:9: warning: toot few arguments for format

만약 함수 선언중 _attribute__(()) 부분을 없애버리면 위의 경고문구는 사라지게 된다.


 

format_arg(string-index)

function_vector

interrupt

ifunc

interrupt_handler

interrupt_thread

isr

kspisusp

l1_text

l2

leaf

long_call/short_call

longcall/shortcall

long_call/near/far

malloc

mips16/nomips16

model(model-name)

ms_abi/sysv_abi

callee_pop_aggregate_return(number)

ms_hook_prologue

naked

near

nesting

nmi_handler

no_instrument_function

no_split_stack

noinline

noclone

nonull(arg-index, ...)

 

noreturn

abort 나 exit 같은 몇몇 표준 라이브러리 함수들은 반환할 수 없다. GCC는 자동으로 이를 안다. 어떤 프로그램들은 함수가 반환하지 않음을 자체적으로 정의할 수 있다. 우리는 noreturn을 선언함으로써 이를 컴파일러에게 일러줄 수 있다.

void fatal() __attribute__((noreturn));

void fatal( /* ... */ )

{

/* ... */ /* Print error message. */ /* ... */

exit(1);

}

noreturn 키워드는 컴파일러에게 fatal 함수가 반환할 수 없음을 일러준다. 그러면 이 fatal 함수가 무엇을 반환하려 하든 관계없이 최적화할 수 있다. 이는 조금 나은 코드를 만들게 하며 더 중요한 것은 초기화되지 않은 변수들에 대해 애매한 경고를 하지 않게 한다.

noreturn 함수가 void 이외의 타입을 갖는 것은 더 이상 의미가 없게 된다.

 

nothrow

optimize

pcs

pure

hot

cold

 

regparm(number)

인텔 386 시스템에서 regparm 속성은 컴파일러로 하여금 첫 번째 함수 인자로부터 number 번째 인자를 스택이 아닌 EAX, EDX ECX 등의 레지스터를 통해 전달하게 한다.

 

sseregparm

force_align_arg_pointer

resbank

return_twice

saveall

save_volatiles

section("section-name")

컴파일러가 생성한 코드는 text 영역에 두는 것이 정상적이다. 그러나 종종 추가적인 영역이 필요하거나 특별한 영역에 두어야 할 특별한 함수를 갖게 되는 경우가 있다. section 속성은 임의의 함수가 특정 영역에 있어야 함을 명기한다. 예를 들어

extern void foobar(void) __attribute__((section("bar")));

와 같이 선언하면 이는 함수 foobar를 bar 영역에 두라는 이야기이다.

어떤 파일형식은 임의의 영역을 지원하지 않으므로 section 속성은 모든 플랫폼에서 이용가능한 것은 아니다. 만약 한 모듈의 모든 내용을 하나의 영역에 두고자 한다면 링커를 이용할 수도 있다.

 

sentinel

short_call

shortcall

signal

sp_switch

 

stdcall

인텔 386 시스템에서 stdcall 속성은 컴파일러로 하여금 함수인자가 가변 개수가 아닌 이상은 인자를 전달하기 위해 사용한 스택영역을 호출된 함수에서 정리(pop off) 하는 것으로 가정하게 한다.

 

syscall_linkage

target

tiny_data

trap_exit

unused

used

version_id

visibility

vliw

warn_unused_result

weak

weakref

weakref("target")


 

 

    

2. 변수속성 (Variable Attribute)

참조 : http://gcc.gnu.org/onlinedocs/gcc-4.6.1/gcc/Variable-Attributes.html#Variable-Attributes

 

 

3. 타입속성 (Type Attribute)

참조 : http://gcc.gnu.org/onlinedocs/gcc-4.6.1/gcc/Type-Attributes.html#Type-Attributes

 


'develop > linux' 카테고리의 다른 글

vi euc-kr, utf-8  (0) 2019.12.24
TTFB 체크 명령어  (0) 2016.02.16
Linux C에서 키보드 이벤트 받기(kbhit())  (0) 2014.02.28
NAT 종류별 설정  (0) 2014.02.17
Linux TCP/IP tunning  (0) 2014.01.08

- 대상 단말에 설치하려는 app의 Provisioning Profile이 저장되어있어야 한다.

- http로 접근 가능한 위치여야 한다. (포트 포워딩을 이용한 개발 서버 등)

- Xcode 5.1.1 기준임.


출처 : http://aaronparecki.com/articles/2011/01/21/1/how-to-distribute-your-ios-apps-over-the-air


1. Xcode에서 빌드 타겟을 IOS Device로 변경


2. 메뉴의 Product-Archive를 선택

2-1. Archive가 끝나면 자동으로 Organizer창이 표시되고, Archives에 지금 빌드한 app이 추가되어 있다.


3. app을 선택 후 "Distribute..."버튼을 클릭한다.

3-1. "Save for Enterprise or Ad Hoc Deployment" 를 선택 후 "Next" 클릭

3-2. Provisioning Profile 선택 후 "Export" 클릭

3-3. 저장위치 설정 창에서 하단의 "Save for Enterprise Distribution"을 체크하면 ipa가 있는 URL과 타이틀을 지정하게 되어 있다.


4. "Save" 를 클릭하면 ipa파일과 plist파일이 생성되는데, 저장 시 입력한 URL로 접근 가능한 위치에 복사한다.


5. 다음과 같은 HTML파일을 생성한다.

<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" /> <title>Install Geoloqi</title> <style type="text/css"> body { background: url(bkg.png) repeat #c5ccd4; font-family: Helvetica, arial, sans-serif; } .congrats { font-size: 16pt; padding: 6px; text-align: center; } .step { background: white; border: 1px #ccc solid; border-radius: 14px; padding: 4px 10px; margin: 10px 0; } .instructions { font-size: 10pt; } .arrow { font-size: 15pt; } table { width: 100%; } </style> </head> <body> <div class="congrats">Congrats! You've been invited to the beta of Geoloqi.</div> <div class="step"> <table><tr> <td class="instructions">Install the<br />Geoloqi app</td> <td width="24" class="arrow">&rarr;</td> <td width="57" class="imagelink"> <a href="itms-services://?action=download-manifest&url=http://loqi.me/app/Geoloqi.plist"> <img src="geoloqi-icon.png" height="57" width="57" /> </a> </td> </tr></table> </div> </body> </html>



1. 아이폰을 Mac에 연결

2. UUID 확인

2.1. Xcode를 사용하여 확인

2.1.1. command-shift-2 (Organizer) 실행

2.1.2. 연결 된 아이폰의 Identifier 복사

2.2. Itunes를 사용하여 확인

2.2.1. Itunes 상단의 iPhone 클릭

2.2.2. iPhone 정보 섹션에서 일련번호 클릭 후 UUID 복사


3. 패킷 미러링 설정

rvictl -s {$UUID}


wireshark로 패킷 캡쳐. rvi0 or rvi1

LTE는 인터페이스 목록에 표시가 되지 않음


4. 패킷 미러링 종료

rvictl -x {$UUID}



기타.

- wireshark가 실행 중에는 패킷 미러링 설정이 안되는 경우도 있다.

- Mac OS의 버전이 10.5이상인 경우 x11이 포함되어 있지 않아 Xquarts를 설치해야 하고, wireShark 첫 실행 시 초기화에 오래 걸림

TCP hole punching 모듈이 있어서 테스트 하려고 다운받으니 jar로 되어 있다.


홈페이지에서 하라는대로 다 하고 android에서 실행하려니 Exception 발생


03-27 16:10:46.123: E/AndroidRuntime(16929): FATAL EXCEPTION: main

03-27 16:10:46.123: E/AndroidRuntime(16929): java.lang.ExceptionInInitializerError

03-27 16:10:46.123: E/AndroidRuntime(16929): at com.ahope.test_tcp_hole.MainActivity.onClick(MainActivity.java:34)

03-27 16:10:46.123: E/AndroidRuntime(16929): at android.view.View.performClick(View.java:4114)

03-27 16:10:46.123: E/AndroidRuntime(16929): at android.view.View$PerformClick.run(View.java:17097)

03-27 16:10:46.123: E/AndroidRuntime(16929): at android.os.Handler.handleCallback(Handler.java:615)

03-27 16:10:46.123: E/AndroidRuntime(16929): at android.os.Handler.dispatchMessage(Handler.java:92)

03-27 16:10:46.123: E/AndroidRuntime(16929): at android.os.Looper.loop(Looper.java:137)

03-27 16:10:46.123: E/AndroidRuntime(16929): at android.app.ActivityThread.main(ActivityThread.java:4885)

03-27 16:10:46.123: E/AndroidRuntime(16929): at java.lang.reflect.Method.invokeNative(Native Method)

03-27 16:10:46.123: E/AndroidRuntime(16929): at java.lang.reflect.Method.invoke(Method.java:511)

03-27 16:10:46.123: E/AndroidRuntime(16929): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:790)

03-27 16:10:46.123: E/AndroidRuntime(16929): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:557)

03-27 16:10:46.123: E/AndroidRuntime(16929): at dalvik.system.NativeStart.main(Native Method)

03-27 16:10:46.123: E/AndroidRuntime(16929): Caused by: java.lang.ExceptionInInitializerError

03-27 16:10:46.123: E/AndroidRuntime(16929): at org.slf4j.impl.Log4jLoggerFactory.getLogger(Log4jLoggerFactory.java:73)

03-27 16:10:46.123: E/AndroidRuntime(16929): at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:242)

03-27 16:10:46.123: E/AndroidRuntime(16929): at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:254)

03-27 16:10:46.123: E/AndroidRuntime(16929): at de.htwg_konstanz.in.uce.hp.parallel.target.HolePunchingTarget.<clinit>(HolePunchingTarget.java:51)

03-27 16:10:46.123: E/AndroidRuntime(16929): ... 12 more

03-27 16:10:46.123: E/AndroidRuntime(16929): Caused by: java.lang.VerifyError: org/apache/log4j/config/PropertySetter

03-27 16:10:46.123: E/AndroidRuntime(16929): at org.apache.log4j.PropertyConfigurator.parseAppender(PropertyConfigurator.java:772)

03-27 16:10:46.123: E/AndroidRuntime(16929): at org.apache.log4j.PropertyConfigurator.parseCategory(PropertyConfigurator.java:735)

03-27 16:10:46.123: E/AndroidRuntime(16929): at org.apache.log4j.PropertyConfigurator.configureRootCategory(PropertyConfigurator.java:615)

03-27 16:10:46.123: E/AndroidRuntime(16929): at org.apache.log4j.PropertyConfigurator.doConfigure(PropertyConfigurator.java:502)

03-27 16:10:46.123: E/AndroidRuntime(16929): at org.apache.log4j.PropertyConfigurator.doConfigure(PropertyConfigurator.java:547)

03-27 16:10:46.123: E/AndroidRuntime(16929): at org.apache.log4j.helpers.OptionConverter.selectAndConfigure(OptionConverter.java:483)

03-27 16:10:46.123: E/AndroidRuntime(16929): at org.apache.log4j.LogManager.<clinit>(LogManager.java:127)

03-27 16:10:46.123: E/AndroidRuntime(16929): ... 16 more


apache의 log4j를 android에서 사용할 수 없다는 것인데...


찾아보니 android에서 직접 사용하는것에 대한 예제와 해결방법은 많은데 내가 원하는것은 없었다..



java 소스를 git로 받아서 로그 출력하는 부분을 주석처리 할까 하다가, jar에 있는 class파일을 변경하면 되지 않을까란 생각이 들었다.


http://www.slf4j.org/download.html 사이트에서 수정된 jar파일을 받아 class파일을 원래 jar에 적용하니 잘 작동한다.






출처: http://androidkr.blogspot.kr/2012/03/mac-mac-os-x-lion-wget.html


Mac Ports 설치 후

  • sudo port selfupdate
  • sudo port install wget


+ Recent posts