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
정현석
이것저것 끄적끄적....

,

Thread 사용법

언어 2010. 8. 31. 09:11

Threads and Thread synchronization
Threads
MFC는 2종류의 쓰레드로 구분할 수 있다.


1. user interface threads
메시지 루프가 존재한다. 윈도우를 만들고 이들 윈도우로 보내진 메시지들을 처리한다. 어플리케이션안에 또하나의 어플리케이션(ui-threads)을 만드는것과 비슷하다.일반적으로 별개로 움직이는 다중 윈도우를 만들때 많이 사용되어 진다.


2. worker threads
직접적으로 메시지를 받지 않고 백그라운드에서 동작되기 때문에 윈도우나 메시지루프들이 필요가 없다.

%이 둘간의실질적인 차이는 아직 잘모르겠다. 좀 더 학습하도록


-Creating a Worker Thread
AfxBeginThread함수는 ui-thread,worker thread 둘다 쓰인다. MFC프로그램에서 Win32::CreateThread함수를 사용하지 말아라.

ex) 
CWinThread* pThread = AfxBeginThread (ThreadFunc, &threadInfo);

UINT ThreadFunc (LPVOID pParam)
{
    UINT nIterations = (UINT) pParam;
    for (UINT i=0; i<nIterations; i++);
    return 0;
}


CWinThread* AfxBeginThread (AFX_THREADPROC pfnThreadProc,
    LPVOID pParam, int nPriority = THREAD_PRIORITY_NORMAL,
    UINT nStackSize = 0, DWORD dwCreateFlags = 0,
    LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL)

nPriority : 쓰레드 우선순위. 쓰레드들 중에서만 상대적인 우선순위를 정할때 사용한다. 
nStackSize : 쓰레드의 스택사이즈 라는데 정확히 뭔지..몰라.
dwCreateFlags : 0 일 경우, 이 함수 호출후 바로 쓰레드가 시작되는 것이고, 
  CREATE_SUSPENDED일 경우, ResumeThread()가 호출되어야지만 시작되는것이다.
lpSecurityAttrs : 몰라도 되.


--Thread Function prototype
콜백함수이기에 static class 멤버 함수이거나 클래스 밖에 선언된 전역함수이어야 한다.
UINT ThreadFunc( LPVOIDpParam )
pParam : 32비트값. AfxBeginThread 함수의 파라미터. 이것은 scalar,handle,객체포인터로도 사용되어 질수 있다.


-Creating a UI Thread
CWinThread를 상속받은 클래스를 사용한다.

ex)
class CMyThread : public CWinThread

CMyThread * pThread = AfxBeginThread(RUNTIME_CLASS(CMyThread),
                                    THREAD_PRIORITY_NORMAL,
                                    0, // stack size
                                    CREATE_SUSPENDED);
pThread->초기값 설정.
pThread->ResumeThread();


또는

CMyThread * pThread = new CMyThread();
pThread->초기값 설정.
pThread->CreateThread();


-Suspending and Resuming Threads
SuspendThread를 호출하면 쓰레드는 멈추고, 내부적으로 Suspend count 가 1 증가 한다. 그리고 ResumeThread를 호출하면 Suspend count는 1 줄고 쓰레드는 다시 움직인다. 
ResumeThread는 자신이 호출 할 수 없다. 그리고 이들 함수의 리턴값은 쓰레드의 이전 Suspend Count이다.


-Putting Threads to sleep
::Sleep(0)  (스레드 양보)
현재쓰레드를 중지하고 스케쥴러가 동등한 혹은 높은 우선순위를 갖는 다른 쓰레드를 움직이도록 허락해준다. 만약, 다른 동등한 혹은 높은 우선순위의 쓰레드가 wait 상태가 아니라면, 이 함수는 바로 리턴해서 현재쓰레드를 재시작 한다. (::SwitchToThread.(in NT 4.0 ), ::Sleep(0) (in win32 ))
Sleep함수의 시간은 정확하지 않을 수 있다. 이는 여러환경에 지배받기때문이다. 윈도우즈에서는 쓰레드의 suspend 시간을 보장하는 함수는 존재하지 않는다.



-Terminating a Thread

--Worker Thread
call AfxEndThread.
쓰레드 함수내부의 리턴으로 종료.


 

--UI Thread
call AfxEndThread.
post WM_QUIT.( ::PostQuitMessage )

(쓰레드 종료함수 사용시 주의할것은 쓰레드 내부에 메모리를 동적할당(new,malloc)해놓고 delete를 안해서 메모리 릭이 날 염려가 있다. 그래서 가급적이면 쓰레드 함수 리턴으로 종료하는 것이 낫다.)

위의 함수들을 호출한 후 한번 제대로 종료됬는지 확인해보라
DWORD dwExitCode;
::GetExitCodeThread (pThread->m_hThread, &dwExitCode);

만약 여전히 살아 있다면 dwExitCode = STILL_ACTIVE(0x103) 으로 되어 있을테다.



 

- CWinThread 개체 자동 삭제하기

AfxBeginThread 로 스레드 생성할 경우,


 

CWinThread *pThread = AfxBeginThread( , ,, );


 

위와 같이 CWinThread 개체 포인터를 반환값으로 받는다. 스레드 종료시, 이 개체는 어떻게 되는가?

MFC는 사용자가 따로 delete pThread; 할 필요없게 자동으로 삭제해 준다.

그런데, 여기서 문제가 있다.

스레드가 종료되지 않았다면, 아래구문은 잘못된 곳이 없다.


 

::GetExitCodeThread( pThread->m_hThread, &dwExitCode );

( 스레드의 현재 상태값을 반환하는 함수 )


 

하지만, 종료되어 pThread 개체 포인터 역시 자동으로 삭제되었다면, 위의 구문은 에러를 발생할 것인다.

pThread 는 아무것도 가리 키지 않기 때문에..


 

해결책)

1. m_bAutoDelete = FALSE; 설정.

-- 이는 곧 사용자가 CWinThread 개체를 delete 해주어야 함을 의미한다.

-- 스레드가 중지가 된 상태에서 m_bAutoDelete = FALSE; 를 설정해주어야 한다.


 

2. Win32::DuplicateHandle 함수를 호출하여 스레드 핸들의 사본을 생성하여 사용.

--해당핸들의 참조카운트가 1 -> 2로 증가되어 CloseHandle() 호출시에 다시 2 -> 1 로 감소될뿐 개체는 죽지 않고 남아있다. 물론, 사용자가 명시적으로 CloseHandle() 을 호출해야 한다.


 

- 다른 스레드 종료하기

1.

//Thread A

nContinue = 1;

CWinThread *pThread = AfxBeginThread( ThreadFunc, &nContinue );

...

...

nContinue = 0 ; // 스레드 B 를 종료해라.



 

//Thread B

UINT ThreadFunc( LPVOID pParam )

{

  int* pContinue = (int*) pParam;

  while( *pContinue )

  {

    ....

  }

  return 0;

}



 

2. 스레드 A는 스레드 B가 죽을때 까지 무한 기다리도록 하고 싶을 경우,


 

//Thread A

nContinue = 1;

CWinThread *pThread = AfxBeginThread( ThreadFunc, &nContinue );

HANDLE hThread = pThread->m_hThread; //사본 생성. 스레드B종료시 pThread 없을 경우 대비.

...

...

nContinue = 0 ; // 스레드 B 를 종료해라.

::WaitForSingleObject( hThread, INFINITE );



 

//Thread B

//1.의 에제와 같음



 

::WaitForSingleObject 은 hThread 스레드가 종료될때 까지 무한정(INFINITE) 기다리는 함수이다.  반환 값은 아래와 같다.

-- WAIT_OBJECT_0 : 그 개체가 신호를 받았다. 즉, 스레드가 종료되었다.

-- WAIT_TIMEOUT : 스레드는 살아있지만, 시간 만료로 기다리지 않고 반환되었다.


 

두번째 매개 변수를 0 으로 설정하고 아래와 같이 사용하는 것이 좋다.


 

if( ::WaitForSingleObject( hThread, 0 ) == WAIT_OBJECT_0 )

//스레드가 더이상 존재치 않는다.

else

//스레드가 여전히 실행중이다.



 

- ::TerminateThread( hThread, 0 );

다른 스레드를 직접삭제하는 방법은 위의 함수 딱 한가지 존재한다. 어쩔 수 없는 경우에만 사용하도록 .



MFC에서 스레드를 사용하기 전에 알아두어야 할 함수는 AfxBeginThread, AfxEndThread 이렇게 두 함수가 있다. 이 함수에 대한 인자값은 MSDN을 참고하기 바라며, 간단한 사용법을 알아보자.

AfxBeginThread(CalcIt, (LPVOID)val);

첫 번째 인자는 전역함수인데, 클래스에 포함시킬 경우 정적함수로 선언해야되고, 아니면 전역함수로 선언해서 써야한다. CalcIt 함수의 리턴값과 파라미터는 아래와 같다.

UINT CalcIt(LPVOID arg);

꼭 위의 규칙을 따라줘야 한다.

일반적으로는 위와 같이 스레드를 시작하면 된다. 그러면 스레드가 시작되고, CalcIt함수(코어 함수??)의 역할이 끝나면 자동으로 스레드를 종료한다.

하지만 스레드는 위와 같이 쓸 경우 바로 리턴해버린다. 리턴값이 0이면 정상적인 종료를 뜻하게 되는데, 사용자에게 의미있는 리턴값을 받기 위해서, 이렇게 하면 안될것이다.

그래서 사용자가 원하는 값을 리턴 받으려면 아래와 같은 방법을 쓴다.

CWinThread* pThread = AfxBeginThread(CalcIt, (LPVOID)val, THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED);
우선 스레드를 시작하지만 정지상태로 놓는다는 뜻이다.(CREATE_SUSPENDED)

그 다음
pThread->m_bAutoDelete = FALSE;
위에서 말했듯이, 스레드가 시작되고 자기 할일이 끝나면 바로 스레드는 종료된다. 하지만 이 값을  FALSE로 해주면 종료되지 않는다. 대신 사용자가 직접 원하는 시점에 종료를 해줘야 한다.(AfxEndThread)

pThread->ResumeThread();
이제 스레드를 시작한다.

그럼 리턴값을 받아야한다.

::GetExitCodeThread(pThread->m_hThread, &returnvalue); //Get ExitCode from thread.

이 함수는 스레드로 부터 리턴값을 읽어온다. 여기에 포함되는 리턴값을 받기 위해선 위의 CalcIt 함수에 AfxEndThread를 써줘야 한다. AfxEndThread함수의 첫 번째 인자는 위 함수의 returnvalue에 들어갈 리턴값이다. 두번째 인자는 스레듣 객체를 메모리에서 제거할 것인지를 나타낸다. 기본값은 TRUE이고 메모리에서 삭제된다. FALSE이면 메모리에 남아있게 되어 스레드 객체를 재사용 할 수 있다.

그리고 마지막으로 알아둬야 할 것이, WaitForSingleObject 함수이다.

역할은 Sleep과 동일하지만, 이 함수의 첫 번째 인자에 있는 스레드가 사용할 수 있게 될 때까지 기다리는 것이다.

Sleep은 스레드를 멈추는 역할밖에 못하지만, WaitForSingleObject는 특정 시간동안 이벤트를 감지할 수 있습니다.

WaitForSingleObject 의 두 번째 인자에는 밀리세컨드 단위의 시간이 들어가는데, INFINITE가 들어가면 스레드가 끝날때까지 기다리게 됩니다.

만약 구현이 된다면 아래와 같은 구조가 될 것이다.

  pThread = AfxBeginThread(ExportVVF, &arg1, THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED); //Make Thread with suspension
pThread->m_bAutoDelete = FALSE; //if this thread will be end, object will not destory this thread.
  pThread->ResumeThread(); //Begin Thread
WaitForSingleObject(pThread->m_hThread, INFINITE);
::GetExitCodeThread(pThread->m_hThread, &returnvalue); //Get ExitCode from thread.


써놓고 보니 정신없네;;;

[출처] AfxBeginThread 사용법|작성자 큐티뽀


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

,
PC 에 설치되어 작동하는 안드로이드

오늘 소개해드릴 내용은 '내 PC 에 직접 안드로이드 OS 를 설치하여, 안드로이드폰 없이 안드로

이드를 
즐기는 방법' 입니다.


가능하냐구요???

이것이 오픈 소스의 위력입니다.

직접 체험해 보세요. 아래 몇 가지만 따라하시면, PC 로 안드로이드 앱을 다운받고, 스카이프로 전화도 

하고, 여러가지를 즐길 수 있답니다. 노트북이나 넷북에 깔아서 사용하시면 더더욱 좋으실듯.


그럼 시작 합니다.

준비물 : 512 MB 이상의 플래쉬 메모리


1. 아래 두 사이트를 방문하여, 설치 파일을 다운로드 받습니다.

http://www.android-x86.org/download


http://unetbootin.sourceforge.net/



2. 다운받은 파일 중 먼저 'UNetbootin' 를 실행 합니다.


플래쉬 메모리를 꽂은 다음, 'UNetbootin' 을 실행 시키고, 'Diskimage' 를 클릭하여 주시고, 

앞서 다운받은 'android-x86-1.6-r2.iso' 파일을 
지정합니다.

밑의 Type 란은 'USB Drive' 를 지정해 주시고, USB 의 드라이브를 설정한 다음 'OK' 버튼을 

누릅니다.


* 물론 USB 드라이브가 아닌, CD or DVD 를 사용하셔도 됩니다. *

3. 자동으로 부팅 디스크를 만듭니다.



완료가 되었으면, 'Reboot Now' 버튼을 눌러서 컴퓨터를 재부팅 합니다.

4. PC를 재부팅할 때 앞서만든 USB 드라이브나, CD or DVD 를 이용하여 부팅을 합니다. 


바이오스에 들어가서, 부팅을 USB 나 CD-ROM 드라이브를 우선 선택 하여 줍니다.


Live CD - Run Android-x86 without installation 을 선택하여 줍니다.


5.  자신의 PC 에 'Android' 글자가 보이며, Android OS 로 부팅이 됩니다.



6. PC 에 안드로이드 OS 가 보이시면, 성공!!



7. 이제 뭘 하면 되나구요?

안드로이드 OS 를 마음껏 즐기시면 됩니다.

안드로이드용 앱도 마음껏 다운로드 해보시고, 앱 사용도 하면서, 즐겨보세요.

노트북을 Wireless 연결하시고, 마이크와 헤드폰이 있으면, 스카이프를 통해 전화도 가능 

하답니다.





* 주의점 *

자신의 노트북이나 PC 가 'AMD' 계열 CPU 면 에러가 상당히 자주 발생하거나, 설치가 되지 

않을수도 있습니다. 그리고, 개발자가 많은 컴퓨터를 테스트 해보았지만, 그래도 몇 가지 기종

에서는 정상작동 하지 않을 수 도 있다고하니, 참고하세요.


http://www.android-x86.org/#Tested_platforms

출처


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

,

1. SDK 빌드 후 Windows용 Binary 적용

2. 우분투에 ARM Compile 및 Lib 설치

3. Android 소스 다운로드 받기 
curl 설치 및 repo 설치

4. java 설치 및 compile 하기

5. ADT Update

6. Andorid 개발 환경 구축(고포릿 노트)

7. 안드로이드 내장 APKs 개발방법 

8. Android Full source compile error일때
(API 수정 후에 해야 하는 작업들)

9. 전체 소스에서 일부만 다시 빌드하는 - mmm command



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

,
사용하고 싶은가? ㅋㅋㅋㅋ

젝일... 이 생각은 왜 못했는지...

Full Build를 하고 sdk build를 하게 되면 AVD를 만들 수 있는 SDK가 생겨난다. 이때!! 기존의 사용하고 있는 SDK의 Path를 새로 생성한 SDK의 Path로 변경해야만!! 아무 이상없이 사용 할 수 있다. 경로변경은 아래와 같이 안내해주는 대로 하면 된다.

1) Eclipse의 Window -> Preferences 선택
2) Android 선택
3) SDK Location 변경


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

,
ㅠㅠ 정말 울고 싶었다... 장작 몇시간을 삽질했는지 모르겠다.... 정동우 대리는 알고 있었다.. 이 방법을....

Android Full source는 다 받아놓고 make 명령만으로도 Build가 가능하다.
Full Build를 하게 되면 out/host/linux-x86/sdk/android-sdk_eng.username_linux-x86/paltforms/android-2.1-update1/ 에 SDK 압축파일이 생성된다.

실제 Android SDK를 설치해주고 AVD에 그곳의 Path를 연결해 주는데 이때 platforms에 
Install했던 Platform Version들이 있을 것이다. 이것들 대신 내가 생성한 android.jar를 사용하기 위해서는 link를 걸어주어야 한다.

ln -s 링크할경로 링크할이름

이렇게 링크를 해주어야 한다. 링크를 해주지 않으면 빌드가 되지 않는다... 젝일... ㅠㅠ 진짜 울고싶다...


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

,
아.. 오늘 정말 개 삽질의 최고봉이였다... Java API를 조금 수정해서 테스트만 해보면 되는 건데 그걸 가지고 13시간을 수정하고 빌드하고 수정하고 빌드하고 왜 안되나 삽질하고 있었다...

java api를 추가하거나 수정한 경우 그냥 make를 하게 되면  아래와 같은 Error Message가 나오게 된다.

You have tried to change the API from what has been previously approved.

To make these errors go away, you have two choices:
   1) You can add "@hide" javadoc comments to the methods, etc. listed in the
      errors above.

   2) You can update current.xml by executing the following commands:

         p4 edit config/api/current.xml
         make update-api

      To check in the revised current.xml, you will need OWNERS approval.

이럴때는 아래와 같이 한다.
$make update-api 
$make

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

,
google Android kernel MS-Windows에서 다운로드 받기

google Android는 현재 MAC OS X 또는 Ubuntu Linux 에서만 컴파일이 가능합니다만, 소스 코드만을 보기위해서면 MS-Windows에서 다운로드하는 것이 좋겠죠. 
문제는 sourceforge.net의 일반적인 프로젝트와는 달리 압축된 파일로 다운로드를 제공하는 것이 아니므로, 별도의 프로그램이 필요합니다. 
일반적인 소스코드관리도구인 CVS나 SVN이 아닌, GIT를 사용하고 있습니다. 
구글에서 한참 찾았는데 의외로 쉬운 곳에 있었습니다. 원래는 첫 화면에 보여주었는데 blog검색에 있어서리 처음에는 찾지 못했습니다.

Android 프로젝트 위치
http://android.git.kernel.org/

GIT 프로그램 위치 
http://code.google.com/p/msysgit/

블로그 위치 
http://bradchow.wordpress.com/2009/01/20/get-android-source-code-in-m-windows/ 

자동으로 download하는 bash shell script 를 소개하고 있습니다.  


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

,
아... 젠장... 정말 케 삽질 했다....

포인터가 없으니 자꾸 C++문법이랑 해깔린다...

뭐냐고? ㅋㅋ 기가차서 어이가 없다. 아래처럼 선언하고서는 사용하고 있었다...

private Map<String, String> m_stMap;

public void setPreferenceForKey(String a_strValue, String a_strKey)
{
m_stMap.put(a_strKey, a_strValue);
}

계속해서 NullPointerException이 일어났고.. 난 문자열이 인자값으로 제대로 들어왔다고 한참 외치고 있었다.... 이게 뭐냐고?? 그래.. 난 저 m_stMap이 그냥 선언했기 때문에 생성되었다고 생각했던 거다.... char* pTest;  pTest->put(A,B); 이렇게 사용한거와 마찬가지인거지...

C++을 계속하다보니 Java를 홀랑 다 까먹는....

그래서 Map을 상속받아 만들어진 HashMap을 사용했다. 사용방법은 거의 동일하다
단, 생성자에서 HashMap에 대한 Instance를 생성해주었다. 

private HashMap<String, String> m_stHashMap;

public wafWidgetControl(){
m_stHashMap = new HashMap<String, String>();
}

public void setPreferenceForKey(String a_strValue, String a_strKey)
{
m_stHashMap.put(a_strKey, a_strValue);
}

이런 실수가 비일비재 할거다.... Java를 너무 오랫동안 안했으니...


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

,
이클립스를 이용하여 Project를 생성 할 때 입력해주어야 하는 것중에

Create Activity 가 있었다... ㅡㅡㅋ 난 이게 뭔가 하고 항상 생각했었는데

이런... 기초적인걸... 알고보니 초기 생성되는 Class 이름이었다...

그러므로 당연히 파일명이 되는것이다... Activity를 상속받는 Class의 이름... 

난 이걸 왜 몰랐을까....

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

,