예전 일본에서 한 2~3주 정도 짬짬히 만들어 본 안드로이드 프로그램입니다.

(이미지 저작권 피하려고, 개인적으로 찍은 사진과, 위키의 타로카드 이미지를 사용했었죠 ㅠㅠ)

 

오랫만에 기억나서 https://play.google.com/apps/publish 로 그동안 통계를 다시 봤는데... 아직 몇몇 분들이 설치해주셔 있군요..

(설치해서 쓰고 있는지, 그냥 설치된채로 버려진 폰인지는... 잘.. ㅠㅠ)

  

아쉽게도 지금 제 현업은 서버프로그래머라, 그냥 옛날에 안드로이드 공부 했다는거에 의의를 두고 있는 작품입니다.

일본에서 밤 12시에 퇴근해서, 이후 새벽 3시까지 저거 혼자 만들면서 즐거워 한 기억이 있네요 (출근이 10시까지였던게..)

 

개발 당시 안드로이드 2.3이 주류 였고, (위의 오른쪽 사진 보시면 ㅠㅠ)

NDK나 그런거 없이 순수 Java 안드로이드 API 작성했었습니다.

 

아마 지금 화면으로 보면 앵크가 깨지고 난리 나지 않았을까 하네요.
하지만 Java , 안드로이드로 뭔가 하나 냈다는거에 의의 두는 앱이였습니다.

 

 

평가를 읽어보니 가슴이 아프더군요... 
그런데... 저걸 공부하기 위해서, 안드로이드 API 익힐겸 만든거라....퀄리티는 제가 생각해도 많이 떨어져요 ㅠㅠ

 

 

 

 

'모바일 프로그래밍 > 안드로이드' 카테고리의 다른 글

안드로이드 종료하는 방법  (0) 2011.07.07
출처 : http://www.androidpub.com/index.php?document_srl=1187851&act=trackback&key=169

<테스트한 코드>

1번> this.finish()

- AndroidManifest.xml 설정 필요 없음

2번> System.out(0)

- AndroidManifest.xml 설정 필요 없음

3번> android.os.Process.killProcess(android.os.Process.myPid());

- AndroidManifest.xml 설정 필요 없음

4번> ActivityManager am = (ActivityManager)activity.getSystemService(Activity.ACTIVITY_SERVICE);
am.restartPackage(activity.getPackageName());

- <uses-permission android:name="android.permission.RESTART_PACKAGES"/>

5번> ActivityManager am = (ActivityManager)activity.getSystemService(Activity.ACTIVITY_SERVICE);
am.killBackgroundProcesses(activity.getPackageName());

- <uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES"/>

<코드 설명>

1번 2번 3번은 테스트를 해본 결과 똑같은 종료방법이다.

하지만 종료되는 시점에 따라 종료가 될 수 있고 안될 수 있다.

ex1)

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

//여기서 1번 2번 3번은 절대 동작 안한다.

onstart에서도 마찬가지이다.

1번 2번 3번으로 종료시키기 위해서는 어떠한 이벤트나 동작이 이루어져야만 작동한다.

한마디로 종료시키는 시점이 중요하다.

ex2)

//A 액티비티

public class A extends Activity {

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

Intent intent = new Intent(this, B.class);
startActivity(intent);

//B 액티비티

public class B extends Activity {

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main2);

//여기서 1번 2번 3번은 절대 동작 안한다.

ex2의 예제는 ex1의 예제와 별다를 것이 없다.

하지만 만약 다른 액티비티를 불러와서 종료시킬 경우

1번 2번 3번을 B의 액티비티에서 쓰려하면 B의 액티비티만 종료된다.

자 그러면 B의 액티비티를 종료시켜보자.

ex3)

public class B extends Activity {

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main2);

Button myButton = (Button) findViewById(R.id.myButton);
myButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//1번 2번 3번으로 종료가 된다!!!!
}
});

ex3의 코드를 보면 B액티비티(2번째)만 종료가 된다. 클릭 이벤트를 발생시켰기 때문에

시점이란 것이 생겼다. 클릭 이벤트가 종료하게 도와준 것이다.

A의 액티비티도 똑같이 종료시키면 된다.

ex4)

public class A extends Activity {

private int a=1;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main2);

if(a==1){
//1번 2번 3번 종료가 된다.
}

ex4번 예제는 if문을 통하여 a변수를 확인하는 시점을 만들어줬다.

A는 종료가 된다.

이런식으로 종료하고 시키고 싶다면 boolean으로 하는것을 추천한다.

true와 false로 선택이 필요한 2가지이니 딱이고,

다른 여러 개발자가 볼때의 입장으로서도 확실하게 이해시키기 편하기 때문이다.

ex5)

//A액티비티

public class A extends Activity {

public static Activity activity; //<==주목하라

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

activity=this;

Intent intent = new Intent(this, B.class);
startActivity(intent);

//B액티비티

public class B extends Activity {

private boolean isB=true;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main2);

if(isB==true){

A.activity.finish(); //<==1번만 가능. A액티비티만 종료된다.

}

Button myButton = (Button) findViewById(R.id.myButton);
myButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {

//버튼 누르면 1번 2번 3번으로 B액티비티 종료시키기
}
});

ex5예제는 많은 분들이 질문하던 현재의 B액티비티안에서 뒤에 있는 액티비티

죽이는 방법이다. 1번만이 가능할 것이다.

1번 2번 3번으로 종료시켜 여러 어플을 만들다보면 분명 다 종료되고 위젯으로

나왔는데 남아있는 경우가 있다. 특히 Service를 extends 하여 사용하면 무조건

남는 경우가 있다.

남는지 안남는지 확인은 여러 방법이 있겠지만 간편한 마켓무료어플인

advanced task killer free를 써서 확인하고 있다.

이 어플은 어떤 어플이 백그라운드에서 살아있는지 이름을 가르켜준다.

이렇게 남아있으면 socket통신할 때 문제가 생기고(접속을 끊었는데 연결이 계속되있는 현상)

스마트폰에도 프로세스를 계속 읽고 있으니 별로 안좋을 것이다.

이럴 때 4번 5번을 쓰면 해결이 된다.

필자는 보통 마지막 종료되는 액티비티나 서비스의 ondestroy에 항상 써주고 있다.

4번은 2.1버전용(ver7)이고, 5번은 2.2버전용(ver8)이다.

그렇다면 매니패스트에서 <uses-sdk android:minSdkVersion="7" /> 에 따라

써야하나?

답은 NO다.

// 7버전 : <uses-permission android:name="android.permission.RESTART_PACKAGES"/>
// 8버전 : <uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES"/>

이 2개의 퍼미션은 같이 써도 무방하다.

그렇다면 4번과 5번의 차이점은 무엇인가?

일단 4번은 2.2버전(ver8)에서도 작동한다.

한마디로 4번만 써도 된다.

5번은 한가지 문제가 있다.

2.1버전 API에는 5번의 함수가 없다.

이클립스에서 new->new android project해서 만들때 Build Target 설정할 때의 버전차이에서 나타난다.

2.1버전으로할 경우 5번의 함수는 없다고 나온다.

5번을 쓸 수 있는 방법은 Build target를 2.2이상으로 바꾸면된다.

이클립스에서 default.properties를 열면 target=android-8로 바꾸면된다.

<uses-sdk android:minSdkVersion="8" /> 이 것도 쓸것이면 같은 8로 바꿔줘야한다.

(에러는 안 나지면 다르면 다르다고 표시는 날것이다.)

ex6)

public class A extends Activity {

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

//4번 5번은 여기서도 종료가 된다.

4번과 5번은 어떠한 시점에서도 종료가 된다. 한마디로 강제종료다!


출처 : http://starplaying.tistory.com/114



아이팟 터치 & 아이폰 개발 with 툴체인 2 아이폰 개발


툴체인 설치를 위해 고생한 분들과 마찬가지로 많은 삽질을 했더랬습니다.

http://date4u.tistory.com/tag/Toolchain 에서 많은 참고를 했었지만 ,

중간에 몇군데 막히는 부분이 있더군요.

따라서 그부분을 추가해서 다시한번 툴체인 설치에 관한 글을 써 볼까 합니다.

(설치한지 며칠 지나서 쓰려니 벌써 기억이 안나기 시작하네요 -_ㅜ)

 

## 혹시 잘 안되는 부분이나 글에 오류가 있으면 덧글 부탁드립니다.

## 며칠전에 했던거라 잘못 쓴 부분이 있을 수도 있기 때문입니다.

 

 

 툴체인 설치과정

 

1. 맥OS X 용 SDK 다운로드

2. 아이폰/아이팟터치용 root filesystem 다운로드

3. 아이폰용 크로스컴파일러가 설치된 cygwin 다운로드 및 설치

4. cygwin에 필요한 파일들 복사 및 설치

5. Hello, world 테스트

6. 이클립스 및 이클립스 CDT 설치 및 연동

7. 이클립스에서 컴파일 하기

 

 

 

 

 

맥OS X용 SDK 다운로드

Xcode 2.5 이미지를 다운로드 합니다.

로그인 후 다운로드가 가능한데, 어짜피 가입해두시는 편이 좋을듯 합니다.

다운받은 이미지는 dmg파일인데, PowerISO라는 프로그램을 통해 가상시디롬으로 만들어서 열어야 합니다.

 

나중에 cygwin을 설치하고 나서 필요한 파일들을 복사하도록 합니다.

 

 

 

아이폰/아이팟터치용 root filesystem 다운로드

아이폰이나 아이팟 터치에서 직접 다운로드 할 수도 있으나, 잘 안된다고 하더군요.

저도 직접 인터넷에서 다운로드 해서 설치했습니다. 일단 1.4용 firmware를 다운로드 합니다.

 

다운로드 후 확장자를 zip으로 변경해 주고 압축파일을 연 다음, 022-3894-4.dmg 파일을 압축해제 합니다.

 

이 글에 첨부된 

 

파일을 다운받아서, 

022-3894-4.dmg 파일과 같은 경로에 넣어준 후,

압축을 풀고 vfdecrypte.exe 파일 및 dll 파일 2개가 생성된것을 확인합니다.

 

cmd 명령으로 쉘을 쉴행시켜서 위 경로로 갑니다. 명령창에,

vfdecrypt.exe -i 022-3894-4.dmg -o trasyia114.dmg -k d0a0c0977bd4b6350b256d6650ec9eca419b6f961f593e74b7e5b93e010b698ca6cca1fe

라고 입력 해서 이미지를 디코딩 하면 trasyia114.dmg 파일이 생깁니다.

이 파일을 나중에 cygwin 설치 후 PowerISO로 열어서 필요한 파일을 꺼내올 겁니다.

 


 

 

 

 

아이폰용 크로스컴파일러가 설치된 cygwin 다운로드 및 설치

Cygwin setup 파일을 다운로드 받아서 실행합니다.

 

아래 그림과 같이 User URL을 http://www.iphonegameover.com/cygwin 으로 입력하고 Add버튼을 눌르면 소스리스트에 위 사이트가 추가되면서 크로스 컴파일러가 설치된 cygwin 패키지가 다운로드 될 준비가 됩니다.

 


 
























 

준비가 되면 아래 그림과 같은 화면이 나오는데, default로 설치 합니다.

(가끔 이화면이 안나오고 에러가 발생하면서 setup.exe가 종료되기도 하는데 이럴때는 다른 pc에서 파일을 로컬에 다운로드하고 복사해 와서 설치해도 됩니다.)

 


 

 

 

 

 

 

cygwin에 필요한 파일들 복사 및 설치

cygwin 설치후 최초로 실행하기 전에, Xcode를 설치 합니다.

위에서 받은 Xcode이미지를 PowerISO로 열어서 아래 경로의 Archive.pax.gz파일을 찾습니다

\Packages\Packages\MacOSX10.4.Universal.Pkg\Contents\Archive.pax.gz

이 파일을 cygwin설치 디렉토리의 home/username/ 아래에 복사해 넣습니다

(c:에 설치하셨다면, c:/cygwin/home/username/ 이 되겠습니다)

 

그리고 위에서 디코딩한 root filesystem 역시 PowerISO로 열어서

/user/local/arm-apple-darwin/filesystem/ 아래에 복사해 넣습니다.

 


 

 

이제 cygwin을 실행해 보면, 자동으로 Archive.pax.gz파일을 찾았다고 나오고 설치가 진행됩니다.

설치가 완료되면 Your tool chain installation is now complete! 라는 메시지가 나오고 설치가 완료됩니다.

 

 

 

 

 

Hello, world 테스트

 이제 Hello, world를 컴파일 해 볼 시간입니다.

이 글에 첨부된 


을 다운받아 압축을 풀고 cygwin에 helloWorld.app라는 디렉토리를 만든뒤 복사해 넣습니다.

컴파일은 make 명령으로 간단히 진행됩니다.

 


 

컴파일 되었으면 실행을 해 볼 차례입니다.

제 경우는 터치밖에 가지고 있지 않으므로, Touch Explorer로 터치의 /Applications 디렉토리에 넣고 실행해 보았습니다 (Jail-break 된 터치라야 업로드가 될겁니다). Auto-permition(권한을 자동으로 설정해주는 어플, 터치 Jail-break 후에 따로 설치해야 함)으로 권한 설정을 해주시면 섬머보드가 재 실행되면서 터치 화면에 추가된 hello, world를 보실 수 있습니다. 실행하면 아래와 같은 화면이 나옵니다.

 

 


 

 

 

 

 

이클립스 및 이클립스 CDT 설치 및 연동

이제 이클립스를 설치하기 위한 준비단계 입니다.

 

먼저 윈도우의 환경변수에서 path를 수정해 줘야 합니다.

cygwin에서 env | grep PATH 명령으로 path를 확인해 보면 아래와 같은데,

/usr/local/bin:/usr/bin:/bin:/usr/X11R6/bin: 라는 부분만 복사를 해서

윈도우의 환경변수중 Path에 추가해 줍니다.

 

당연히 경로는 c:\cygwin 아래 일 것이므로

c:\cygwin\usr\local\bin;c:\cygwin\usr\bin;c:\cygwin\bin;c:\cygwin\usr\X11R6\bin

의 형태로 추가를 해주시면 됩니다.

 

include경로 추가도 해줘야 하므로

윈도우의 환경변수에 include라는 변수이름을 추가하고 변수값에는

c:\cygwin\usr\local\arm-apple-darwin\include

를 추가해 줍니다.

 

이제 이클립스 for C, C++를 다운로드 합니다.

그리고 이클립스 CDT도 다운로드 합니다.

 

먼저 이클립스를 설치 한 후, 실행 합니다.

아래 그림처럼 Help > Software updates > Find and install 을 실행합니다

 


 

 

 

여기서 Search for new features to install을 선택하고

New Archived Site... 로 들어가서 아까 다운로드한 CDT zip파일을 선택한 후 설치합니다.

 


 

 

 

이제 자잘한 설정이 남았습니다.

 

이클립스를 닫은뒤 재실행 하시고, Window > Preference... 로 가셔서

C/C++ > NewCDT project wizard > Makefile Project 로 가셔서

아래 그림처럼 Elf Parser, Cygwin PE Parser, GNU ELF Parser 를 체크해 줍니다.

(만약 New CDT project wizard 항목이 없다면 CDT설치가 잘못된것입니다.)

 

그리고 Error Parsers 탭에서 모두 선택합니다.

 


 

 


 

 

 

자 이제 준비가 거의 끝났습니다.

다른 포스트에서 본 경우에는 이후 정상적으로 컴파일이 되었다고 하는데, 제 경우엔 잘 되지 않아서 이리저리 고민하다 알아낸 것이 추가적인 이클립스 내의 경로 설정입니다.

(혹시 컴파일 할때 Exec error: Launching failed 라는 메시지가 뜨신다면 이 방법으로 해결이 될겁니다)

 

Window > Preference... 로 가셔서 C, C++ > Environment로 갑니다.

New를 선택하고 Name에 PATH를 Value 에 윈도우의 환경변수 Path와 같은 내용을 써 줍니다.

 


 

 

 

 

 

 

이클립스에서 컴파일 하기

File > New... > C project 로 가서 새 프로젝트를 생성합니다.

모두 default로 합니다.

 


 

 

 

아까 cygwin에서 썼던 hello, World 소스를 import 합니다.

프로젝트 이름 우클릭 > import

 


 

 

 

General에서 file system을 고른후 hellow, Wolrd 파일들을 압축 풀어둔 디렉토리를 선택하면

아래처럼 파일들을 골라서 import할 수 있습니다.

 


 


 

 

이제 컴파일을 해 봅니다.

 

Project > Clean... 으로 컴파일을 하시면 아래와 같이 나와야 정상적으로 컴파일이 된 것입니다.

수고하셨습니다.

 


 

 

 

길고긴 포스팅이 드디어 끝이났네요.

다음 포스팅이 언제가 될지는 저도 모릅니다. 배워가면서 하는입장이라서요 ^^.

그럼 즐거운 개발들 되시기 바랍니다.

+ Recent posts