'java'에 해당되는 글 134건

  1. 2008.07.05 [Link] 자바 JVM에 대한 튜닝에 대한 자료가 잘 정리되어 있는 사이트
  2. 2008.07.05 [Link] AIX (IBM JVM사용시)에서의 자바 문제 해결 방법
  3. 2008.06.28 [세미나자료] 2008년 07월 18일 OKJSP 세미나 자료. (1)
  4. 2008.06.13 [Memory leak] Oracle의 OCI를 사용할 때 C Heap 과 관련된 OutOfMemoryError가 발생할 때
  5. 2008.06.04 [Java Basic] 자바 주석 (자바 코멘트) 관련 문서
  6. 2008.05.15 [Java Basic] Regular Expression (정규식, 정규 표현식)의 형식
  7. 2008.05.14 [Java Basic] Regular Expression (정규식, 정규 표현식)의 기본
  8. 2008.04.28 [Blog2Book] 자바 성능을 결정 짓는 코딩 습관과 튜닝 이야기 책에 대한 다양한 이야기들 (1)
  9. 2008.04.16 [Good Article] C++로 돌아가는 자바를 읽고
  10. 2008.04.11 [Google Android-구글 안드로이드] 본격적으로 만들어 보기-5 Activity 추가하기~~~
  11. 2008.04.02 [Spring] 초간단 Spring MVC 구현하기
  12. 2008.04.02 [Spring] Spring MVC에 대한 기초중의 기초
  13. 2008.04.02 [eclipse 팁] 이클립스의 신기한 기능
  14. 2008.04.01 [링크] 자바의 어노테이션 (Annotation)
  15. 2008.04.01 [Spring] AOP 의 Proxy를 보다 쉽게 이해하기 위한 Proxy 패턴 예제
  16. 2008.04.01 [Spring] AOP(Aspect Oriented Programming) 란?
  17. 2008.03.31 [Spring] IoC와 DL과 DI
  18. 2008.03.31 [eclipse] eclipse를 시작할때 JVM terminated exit code=-1 이 뜨면서 제대로 시작이 되지 않을때
  19. 2008.03.31 [Spring] Spring Framework (스프링 프레임웍) 이란?
  20. 2008.03.31 [Spring] Spring Framework의 등장배경
  21. 2008.03.28 [DevPartner] 메모리 프로파일링 하기
  22. 2008.03.27 [DevPartner] 성능 프로파일링 하기
  23. 2008.03.26 [Weblogic] 웹로직(Weblogic) 서버 쓰레드(Thread) 및 DB connection Pool 관련 설정
  24. 2008.03.21 [Google Android-구글 안드로이드] 본격적으로 만들어 보기-4 Activity 클래스를 보다 간결하게 만들기
  25. 2008.03.21 [Google Android-구글 안드로이드] 본격적으로 만들어 보기-3 연습용 메인 프로젝트 만들기(안드로이드 메뉴 처리)
  26. 2008.03.21 [Google Android-구글 안드로이드] ddms 사용하기 (안드로이드 화면 캡쳐하기)
  27. 2008.03.15 [Blog2Book] 자바 성능을 결정짓는 코딩 습관과 튜닝 이야기 책에 있는 소스 코드 ver.1.1. (1)
  28. 2008.03.12 [Google Android-구글 안드로이드] 본격적으로 만들어 보기-2 연습용 메인 프로젝트 만들기(메시지 화면 처리) (1)
  29. 2008.03.09 [Google Android-구글 안드로이드] 본격적으로 만들어 보기-1 연습용 메인 프로젝트 만들기
  30. 2008.03.07 [eclipse - 이클립스] Workspace in use or cannot be created, choose a different one. 이라는 메시지가 나타날때 (5)
http://ukja.tistory.com/category/Enterprise%20Java

이 글을 작성하신 분께서는 JVM 떄문에 단단히 고생하신것 같다. ^^;

제 책에 있는 메모리 부분에 대한 설명을 읽은 후 이 블로그에 있는 글을 읽으시면 굉장히 많은 도움이 되겠네요.

특히 IBM JVM의 가장 큰 문제인 Compaction 문제에 대해서도 정리가 잘 되어 있다.
Posted by tuning-java
http://www.ibm.com/developerworks/kr/library/au-javaonaix_memory.html

AIX 서버 (IBM JVM을 사용하는 서버)에서 자바 관련 문제가 발생되었을때 해결방안이 정리되어 있다.

그중 가장 마음에 드는 구절은 다음 부분이다. ^^;

메모리 문제는 매우 복잡하고, 해결하기도 매우 어려우며, 진단에도 많은 시간이 요구됩니다. 메모리 관련 문제들은 다음과 같은 이유로 인해 해결하기 매우 어려운 작업입니다.

  • 부적절하게 튜닝 된 OS나 JVM
  • 부적절하게 객체를 관리하는 자바 애플리케이션
  • 부적절하게 할당된 큰 객체 또는 중첩 객체들
  • 단편화(Fragmentation)
  • JNI/네이티브 코드에서 올바르게 릴리스 되지 못한 메모리
  • JVM 메모리 할당과 사용에 대한 이해의 부족

ㅋㅋㅋ

Posted by tuning-java



2008년 7월 18일 OKJsp 와 함께하는 세미나에서 발표할 자료입니다.

원본을 PDF로 변환하였습니다.

상황에 따라서 내용이 변경될 수 도 있습니다.

여기에 있는 모든 내용은 불펌하시면 안됩니다. ^^;

만약 가져가실 경우 출처를 명시해 주시기 바랍니다.

(뭐 가져가셔도 별 필요는 없겠지만.. ㅋㅋ)

컬러판은
http://www.slideshare.net/javatuning/okjsp-performance-and-java-tuningv20080702/
에서 확인하실 수 있습니다.

Posted by tuning-java

http://www.jennifersoft.com/46/forum/page/3/show/1130.html

메모리 릭을 발생시키는 원인은 무척 많지만,
Oracle의 OCI를 사용할때 C Heap이 계속 누적되어 OutOfMemoryError가 발생할 수 있다고 한다.

데이터 건수가 적을때는 조금씩 쌓여도 간에 기별도 안가겠지만,
화면에서 제대로 처리하지 못하고 3만, 10만건을 조회하다가 오류가 발생하면 이러한 문제가 발생할 수도 있다.


 

Posted by tuning-java
http://java.sun.com/j2se/javadoc/writingdoccomments/

자바로 개발하다 보면, 주석을 잘 정리하지 않는 경우가 있는데
-나중에 내가 이 메소드를 왜 만들었는지,
-무슨 역할을 하는 클래스인지
를 기억 못하는 경우가 종종 있다.

그리고 추후에 Java doc 문서를 만들때 필요한 요소들을 모르면 제대로 된 문서가 생성되지 않는다.

위에 있는 링크를 참조하여, 반드시 자신의 클래스에 주석을 다는 버릇을 들이자.
특히 이 버릇은 정말 고치기 힘들다.

참고로 eclipse에서는 comment를 달기 위해서 해당 메소드나 클래스의 블록 안에서 Alt+Shift+J 를 누르면, 기본적인 주석이 생성된다.

public class A {
  //지점 1
  public void methodB () {
    //지점 2
  }
}

즉 지점 1에서 단축키를 누르면 클래스의 주석이 자동 생성되고,
지점 2에서 단축키를 누르면 메소드의 주석이 자동 생성된다.
Posted by tuning-java

자바 API에 있는 java.util.regex 패키지의 Pattern 클래스를 보면 정규식을 표현하는 Construct가 나와 있다.
http://java.sun.com/javase/6/docs/api/java/util/regex/Pattern.html

아래 내용은 Java JDK에 있는 내용을 재 정리 한것이다. (시간이 되면 번역을 할까 생각중인데, 궂이 그럴필요가...)

가장 먼저 특수 문자에 대해서 알아보자. 각각의 8진수, 16진수, tab, 이스케이프 문자등을 나타내기 위해서는 다음과 같이 사용하면 된다.

x The character x
\\ The backslash character
\0n The character with octal value 0n (0 <= n <= 7)
\0nn The character with octal value 0nn (0 <= n <= 7)
\0mnn The character with octal value 0mnn (0 <= m <= 3, 0 <= n <= 7)
\xhh The character with hexadecimal value 0xhh
\uhhhh The character with hexadecimal value 0xhhhh
\t The tab character ('\u0009')
\n The newline (line feed) character ('\u000A')
\r The carriage-return character ('\u000D')
\f The form-feed character ('\u000C')
\a The alert (bell) character ('\u0007')
\e The escape character ('\u001B')
\cx The control character corresponding to x

그 다음에는 문자를 표현하는 방식을 보자. 특정 범위의 문자나 범위 이외의 문자는 다음과 같이 표시한다.

[abc] a, b, or c (simple class)
[^abc] Any character except a, b, or c (negation)
[a-zA-Z] a through z or A through Z, inclusive (range)
[a-d[m-p]] a through d, or m through p: [a-dm-p] (union)
[a-z&&[def]] d, e, or f (intersection)
[a-z&&[^bc]] a through z, except for b and c: [ad-z] (subtraction)
[a-z&&[^m-p]] a through z, and not m through p: [a-lq-z](subtraction)

위의  방식을 사용하여 정의할 수도 있겠지만, 다음과 같이 미리 정의된 문자열을 사용하면 보다 편하게 사용 가능하다.

. Any character (may or may not match line terminators)
\d A digit: [0-9]
\D A non-digit: [^0-9]
\s A whitespace character: [ \t\n\x0B\f\r]
\S A non-whitespace character: [^\s]
\w A word character: [a-zA-Z_0-9]
\W A non-word character: [^\w]

그리고, POSIX 문자열을 사용할 경우에는 다음과 같이 정의할 수 있다.
(참고로 POSIX가 뭔지 모르시는 분은 http://ko.wikipedia.org/wiki/POSIX 를 참조하시면 쉽게 이해 될것이다.)

\p{Lower} A lower-case alphabetic character: [a-z]
\p{Upper} An upper-case alphabetic character:[A-Z]
\p{ASCII} All ASCII:[\x00-\x7F]
\p{Alpha} An alphabetic character:[\p{Lower}\p{Upper}]
\p{Digit} A decimal digit: [0-9]
\p{Alnum} An alphanumeric character:[\p{Alpha}\p{Digit}]
\p{Punct} Punctuation: One of !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~
\p{Graph} A visible character: [\p{Alnum}\p{Punct}]
\p{Print} A printable character: [\p{Graph}\x20]
\p{Blank} A space or a tab: [ \t]
\p{Cntrl} A control character: [\x00-\x1F\x7F]
\p{XDigit} A hexadecimal digit: [0-9a-fA-F]
\p{Space} A whitespace character: [ \t\n\x0B\f\r]

자바의 Character 클래스와 같은 방식으로 사용하려면 다음과 같이 사용 가능하다.

\p{javaLowerCase} Equivalent to java.lang.Character.isLowerCase()
\p{javaUpperCase} Equivalent to java.lang.Character.isUpperCase()
\p{javaWhitespace} Equivalent to java.lang.Character.isWhitespace()
\p{javaMirrored} Equivalent to java.lang.Character.isMirrored()

유니코드를 처리하기 위해서는 다음과 같이 사용하면 된다. (한글에 대해서는 아직 테스트 해보지 않았다. ^^)

\p{InGreek} A character in the Greek block (simple block)
\p{Lu} An uppercase letter (simple category)
\p{Sc} A currency symbol
\P{InGreek} Any character except one in the Greek block (negation)
[\p{L}&&[^\p{Lu}]]  Any letter except an uppercase letter (subtraction)

각 경계값을 나타내는 것은 다음과 같이 할 수 있다.

^ The beginning of a line
$ The end of a line
\b A word boundary
\B A non-word boundary
\A The beginning of the input
\G The end of the previous match
\Z The end of the input but for the final terminator, if any
\z The end of the input

이제부터 정신을 바짝 차려야 하는데, 위의 각 방법을 조합해서 각 문자의 횟수를 다음과 같이 지정할 수 있다.
(이를 Greedy quantifiers라고 부른다.)

X? X, once or not at all
X* X, zero or more times
X+ X, one or more times
X{n} X, exactly n times
X{n,} X, at least n times
X{n,m} X, at least n but not more than m times

그리고, ? 와 +를 사용하여 각각 제외 및 포함의 의미를 나타낸다. 각 예는 다음과 같다.

Reluctant quantifiers
X?? X, once or not at all
X*? X, zero or more times
X+? X, one or more times
X{n}? X, exactly n times
X{n,}? X, at least n times
X{n,m}? X, at least n but not more than m times

Possessive quantifiers
X?+ X, once or not at all
X*+ X, zero or more times
X++ X, one or more times
X{n}+ X, exactly n times
X{n,}+ X, at least n times
X{n,m}+ X, at least n but not more than m times

논리 부분은 다음과 같이 표시한다.

XY X followed by Y
X|Y Either X or Y
(X) X, as a capturing group

특수 Construct는 다음과 같다.

(?:X) X, as a non-capturing group
(?idmsux-idmsux)  Nothing, but turns match flags i d m s u x on - off
(?idmsux-idmsux:X)   X, as a non-capturing group with the given flags i d m s u x on - off
(?=X) X, via zero-width positive lookahead
(?!X) X, via zero-width negative lookahead
(?<=X) X, via zero-width positive lookbehind
(?<!X) X, via zero-width negative lookbehind
(?>X) X, as an independent, non-capturing group

기타 관련 Construct들은 다음과 같다.

Back references
\n Whatever the nth capturing group matched

Quotation
\ Nothing, but quotes the following character
\Q Nothing, but quotes all characters until \E
\E Nothing, but ends quoting started by \Q

이 내용들에 대해서는 한번 쭉~~~ 읽어보면 이해가 되겠지만, 예제를 봐야지만 보다 더 쉽게 이해할 수 있으리라 생각된다.

다음 글에는 예제를 통해서 각 Regular Expression을 어떻게 사용하는지 정리하도록 하겠다.

Posted by tuning-java

String 데이터를 처리하기 위한 코딩을 할 때 알아두면 굉장히 도움 되는 것이 Regular Expression이다.

이게 뭔지도 모르신다면, 아래의 링크를 따라가서 한번 읽어 보시기를 권장한다.

http://java.sun.com/docs/books/tutorial/essential/regex/index.html

예를 들어 e-mail 주소나 URL의 정합성을 체크할 때 굉장히 편하게 사용할 수 있다.
Regular Expression을 주로 사용하는 언어들은 grep, Perl, Tcl, Python, PHP, awk 등이 있다.

Java 에서도 JDK 1.4 버젼부터 Regular Expression을 사용하기 시작했으며, java.util.regex.Pattern 클래스의 API 를 보면 Regular Expression에서 사용되는 패턴 구성을 볼 수 있다.

참고로,이미 만들어진 Regular Expression 들을 참조하고 싶다면, 아래의 사이트를 방문하기 바란다.
http://regexlib.com/

그럼 간단하게 Java를 이용해서 Regular Expression을 사용하는 방법에 대해서 알아보자.

import java.util.Scanner;
import java.util.regex.Pattern;
import java.util.regex.Matcher;

public class RegexTester {

    public static void main(String[] args){
        RegexTester rt=new RegexTester();
        while(true) {
            rt.checkRegularExpression();
        }
    }
    public void checkRegularExpression() {       
        Scanner sc=new Scanner(System.in);
        System.out.print("Enter Regular expression pattern : ");
        String regex=sc.nextLine();
        while(check(regex));
    }
    public boolean check(String regex) {
        Scanner sc=new Scanner(System.in);
        System.out.print("Enter data: ");
        String data=sc.nextLine();
            Pattern samplePattern = Pattern.compile(regex);
            Matcher matcher = samplePattern.matcher(data);
            boolean found = false;
            while (matcher.find()) {
                System.out.format("Text \"%s\" is found : from index %d - to index %d.\n",
                    matcher.group(), matcher.start(), matcher.end());
                found = true;
            }
            if(!found){
                System.out.format("No match found.\n");
            }
            System.out.print("Check another data ? [Y or y] or Quit [Q or q] : ");
            String another=sc.nextLine();
            if(another.equals("Q") || another.equals("q")) {
                System.exit(0);
                return false;
            } else if(another.equals("Y") || another.equals("y")) {
                return true;
            } else {
                return false;
            }
    }

}

이 프로그램은 Regular Expression을 입력하고, 문자열을 입력하면 입력된 문자열중 Regular Expression과 맞는 (match되는) 문자열이 어떤것이 있는지를 화면에 뿌려준다.

실행 결과 예는 다음과 같다.

Enter Regular expression pattern : [abc]
Enter data: abcdefg
Text "a" is found : from index 0 - to index 1.
Text "b" is found : from index 1 - to index 2.
Text "c" is found : from index 2 - to index 3.
Check another data ? [Y or y] or Quit [Q or q] : y
Enter data:
No match found.
Check another data ? [Y or y] or Quit [Q or q] : y
Enter data: cbfhgft
Text "c" is found : from index 0 - to index 1.
Text "b" is found : from index 1 - to index 2.
Check another data ? [Y or y] or Quit [Q or q] : q

다음 글에는 Regular Expression을 어떻게 지정하는지 알아보자.

Posted by tuning-java

책이 나온지 거의 두달 되어가니 여러분들의 이야기들이 블로그에 올라와 있다.

좋은 리뷰도 있고, 좋지 않은 리뷰도 있네요. 모든 의견이 중요하다고 생각합니다.

단지, 이 책에서 부족하다고 생각들 하시는 튜닝의 기법이라든지, 툴에 대한 자세한 내용은 다음 책을 위해서 아껴 두었다고 너그럽게 생각해 주시면 감사하겠습니다.

이 책을 사려는 분들이나, 다양한 의견을 공유하시려는 분들은 아래의 링크를 클릭해 보시면 됩니다. ^^;

<<<<< Yes24 사이트의 주옥같은 리뷰들 보기 >>>>>

최종 update date : 2008. 05. 10.

Posted by tuning-java

IBM developerWorks 뉴스레터를 보다가 괜찮은 글을 하나 발견했다. 링크는 아래에...

http://www.ibm.com/developerworks/kr/library/dwclm/20080408/

내 생각도 이 글의 필자와 크게 다르지는 않다. 

예전부터 해온 생각이 "굳이 이렇게 자바를 확장할 필요가 있을까? "라는 것이다.

지금까지의 자바를 보다 안정적이고, 보다 빠르게 개선하는 것이 더 중요하다고 생각한다.

프로그래밍 언어의 버젼이 개발툴 버젼처럼 지속적으로 빠르게 올라갈 필요는 없다고 생각한다.

오히려 그 언어를 사용하는 "프레임웍"들을 보다 더 좋게 향상 시키는 것이 낫지 않을까?

Posted by tuning-java
TAG java, 자바

이제 메인 화면에서 다른 화면으로 전환하는 Activity를 만들어보자.

(아마도 제가 쓰는 글을 계속 읽어오신 분들은 이 부분에 대해서 많이 궁금해 하셨을 것이라 생각한다. 그리고 물론 쉽지도 않다.)

다음과 같이 클래스를 하나 맹근다.

이제, 다음과 같이 소스를 작성하자.

package com.min.summary.layouts;

import android.app.Activity;
import android.os.Bundle;

import android.view.ViewGroup.LayoutParams;
import android.widget.Button;
import android.widget.RelativeLayout;
public class RelativeTest extends Activity {
    RelativeLayout relativeLayout;
    LayoutParams lpFillFill=new RelativeLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        relativeLayout=new RelativeLayout(this);
        relativeLayout.setLayoutParams(lpFillFill);
        setContentView(relativeLayout);
    }
}

그럼 바로 앞서 만든 MainButtonManager 클래스의 setButtons() 메소드에 다음과 같은 버튼을 만들자.

        Button relBut=new Button(parent);
        relBut.setText("Show relative layout");
        relBut.setOnClickListener(new OnClickListener() {
            public void onClick(View view) {
                Intent intent = new Intent(parent,com.min.summary.layouts.RelativeTest.class);
                parent.startActivity(intent);

            }
        });
        parentLayout.addView(relBut, lpFillWrap);

intent 객체를 만들어서 부모에서 startActivity 메소드에 intent 객체를 넘겨주면 된다.
(정확하게 이렇게 intent객체를 만드는 이유에 대해서는 좀더 공부해 봐야겠다.)


이제 한번 실행해 볼까?

새로 추가된 버튼이 추가되었다. ㅋㅋ

한번 눌러보자.

어라? 이게 뭐야?
에러가 난다. 에러를 잘 읽어보자.


AndroidManifest.xml 파일에 내가 추가한 클래스를 선언한걸 못찾겠단다.
하래면 해야지머...

AndroidManifest.xml 파일을 더블클릭하면, 안드로이드 어플리케이션 설정 화면이 나타난다.
거기서 두번째 탭에 있는 Application을 클릭하자.
하단에 있는 Appilcation Nodes 에서 "Add..." 버튼을 클릭하자.
그 다음 나타나는 팝업 화면에선 Activity를 클릭하자.

여기서 일단 돌아가게하려면 입력해야 하는건 달랑 하나~~ "Class Name*" 이라고 되어 있는 곳에서 "Browse" 버튼을 클릭한다.

마지막으로 해야하는 것은 새로 만든 .layouts.RelativeTest 를 추가하는 것 뿐이다.

결과는 다음과 같다.

까만화면이닷~~~. - -;

왜냐하면, 아무것도 RelativeLayout에 추가하지 않았기 때문이다.

그러면 다음 글에는 RelativeLayout을 사용하는 방법에 대해서 알아보자.

Posted by tuning-java

Eclipse를 사용하여 Spring MVC 을 구현하는 것에 대해서 알아보자.

일단 가장 먼저 Eclipse에서 Dynamic Web Project를 맹글자.
(이 부분은 다 알고 있으리라 생각하고 패쑤~~)

그 다음 맹글어진 프로젝트에서 WebContents 밑에 있는 web.xml을 열자.
web.xml 파일의 </web-app> 태그 위에 아래의 내용을 복사하여 붙이자.
-------------------------------------------------------------------
<servlet>
  <servlet-name>action</servlet-name>
  <servlet-class>
   org.springframework.web.servlet.DispatcherServlet
  </servlet-class>
  <init-param>
   <param-name>contextConfigLocation</param-name>
   <param-value>
    /WEB-INF/action-servlet001.xml
   </param-value>
  </init-param>
  <load-on-startup>1</load-on-startup>
 </servlet>

 <servlet-mapping>
  <servlet-name>action</servlet-name>
  <url-pattern>*.do</url-pattern>
 </servlet-mapping>
------------------------------------------------------------------------
잘 붙였으면, 간단하게 내용을 살펴보자.
DispatcherServlet은 말 그대로 Servlet 클래스이기 때문에 web.xml에 추가한 것이고,
앞으로 모든이름.do를 호출하면 이와 관련된 클래스가 호출될 것이다.
중간에 action-servlet001.xml이라는게 아직 없다.
없으니 만들자...

WEB-INF 디렉토리 하단에 action-servlet001.xml 을 다음과 같이 만들자.
------------------------------------------------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:context="http://www.springframework.org/schema/context"
 xmlns:p="http://www.springframework.org/schema/p"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://www.springframework.org/schema/beans  
       http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-2.5.xsd">

 <bean id="handlerMapping"
  class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" />
 
 <bean name="/test.do"   class="test.TestController">
  </bean>

</beans>
-----------------------------------------------------------------------------------
내용은 모른다고 치더라도 test.TestController 라는 클래스가 필요하다고 느낄것이다.
웹에서 test.do를 수행하면 해당 컨트롤러 클래스가 호출될 것이다.

test.TestController 클래스는 다음과 같다.
----------------------------------------------------------------------------------
package test;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

public class TestController implements Controller {
 public ModelAndView handleRequest(HttpServletRequest request,
   HttpServletResponse response) throws Exception
{
  System.out.println("TestController ==> handleRequest");
  return new ModelAndView("redirect:/index.html");
 }
}
-------------------------------------------------------------------------
이 소스에서는 다른 일은 안하고 "TestController ==> handleRequest"를 프린트하고
index.html로 forwarding 하도록만 되어있다.
그럼 마지막으로 이클립스의 WebContents 폴더 하단에 index.html을 하나 생성하자.
html의 body에는 다음과 같이 한번 넣어볼까?
-------------------------------------------------------------------------
<body>
Thank you for follow this tutorial. hahaha.
</body>
-------------------------------------------------------------------------
그럼 이제 코딩해야 할일은 다 끝났다.

하지만 두가지 일이 남아있다.
만든 클래스가 이클립스의 build 폴더에 생성이 되어있지 않으니,
eclipse 메뉴에서 Project --> Build All을 클릭하여 클래스를 빌드해야 한다.
(뭐~ 이게 자동으로 될 수도 있다.)

또 한가지 남은 것은
WEB-INF 하단의 lib 폴더에 Spring framework과 관련된 모든 jar를 집어 넣어 줘야 한다.
(이 방법도 여러분만의 방법이 있을 테니 자세한건 패스하고...
가장 간단한 것은 익스플로러에서 모든 jar를 선택하고 eclipse에 끌어 넣어주면 된다.)

정상적으로 작업이 되었다면
tomcat을 띄워서 해당WebApp/test.do 를 실행해보자.
Tomcat의 console에
"TestController ==> handleRequest"
가 출력되고,
화면에
Thank you for follow this tutorial. hahaha.
가 나타났다면,
초 간단 Spring MVC Framework 실습이 완료된 것이다.

이제 천천히 어려운 부분을 공부해 보자.

Posted by tuning-java

일단 본론에 들어가기 전에 MVC에 대해서는 다 알꺼라 생각한다. 몇줄만 적어보면

MVC는 Model, View, Controller의 약자로 예전의 UI, DB처리, 비즈니스 로직을 하나의 클래스나 파일에서 처리하던 것을 분리하는 것을 말한다.

간단하게 몇줄만 적었다. ㅋㅋ
그럼 Spring MVC 프레임웍에서 어떻게 사용자 요청이 처리되는지 알아보자.

1. 사용자의 요청이 오면 DispatcherServlet이라는 것이 받는다. 얘를 앞단 중계자라는 의미로 Front Controller라고 부른다.
2. 받은 것을 뭔가 매핑이 되어 있는 곳에서 적절한걸 찾아서 다른 곳으로 전달한다. 이 것을 핸들러라고 한다.
3. 전달 받은 데이터를 기반으로 DB에서 데이터를 얻어온 다음에 ModelAndView라는 객체에 저장해서 넘긴다고 한다.
4. 그 다음 DispatcherServlet이라는 놈에서 화면에 보여줄 View 와 Model 정보를 View Resolver라는 것을 통해서 View를 결정한다.
5. 해당 View에 데이터를 넘기고, View에서는 화면을 처리한 결과를 DispatcherServlet으로 넘긴다.
6. 마지막으로 화면으로 보내준다.

이 내용을 그림으로 표현한 것이 바로 아래 링크에 있다.
http://static.springframework.org/spring/docs/2.0.x/reference/mvc.html
마우스 스크롤이 어떻게 되어 있느냐에 따라서 다르겠지만, 한 3번 정도 스크롤하면 볼 수 있다. ^^;

자세한 구현 방법은 다음 글에 올리도록 하겠다.

Posted by tuning-java
만약 여러분의 클립보드에 다음의 내용이 있다고 치죠. (아래의 내용을 복사하거나 Ctrl-C 를 누른 경우)
//내용 시작
package test;
public class Test {
}
//내용 끝

이클립스에서 src 를 누른 후 Ctrl-V를 눌러보자.

그럼 짜잔~~~
하고 여러분의 이클립스에 클래스가 하나 추가되면서, 그 내용이 에디터에 나타날 것입니다.


Posted by tuning-java
자바의 어노테이션이란 것이 JDK 5.0 부터 생겨났기 때문에,
예전부터 자바를 하신분들은 이해하기가 다소 어려울 수 있다.
그럼 어노테이션이란건 왜 만들어서 사람을 귀찮게 할까 ?
궁금하다면, 다음의 글을 읽어보자.
(참고로 한글이다....)

http://www.ibm.com/developerworks/kr/library/j-annotate1/index.html


http://www.ibm.com/developerworks/kr/library/j-annotate2.html
Posted by tuning-java
먼저 아래의 간단한 소스를 읽어 보자.

package proxytest;
public interface ITempLogic {
 public String greet();
}
----------
package proxytest;
public class TempLogicImpl implements ITempLogic {
 public String greet() {
  return "Hi";
 }
}
----------
package proxytest;
public class TempLogicProxy implements ITempLogic {
 private ITempLogic itl=null;
 public TempLogicProxy(ITempLogic l) {
  itl=l;
 }
 public String greet() {
  System.out.println("before");
  String r=itl.greet();
  System.out.println("after");
  return r;
 }
 public static void main(String args[]) {
  ITempLogic l=new TempLogicProxy(new TempLogicImpl());
  System.out.println(l.greet());
 }
}
----------
 간단하게 소스에 대해서 설명을 하자면,
 ITempLogic이라는 인터페이스를 하나 만들고,
 해당 인터페이스를 구현한 TempLogicImpl 이라는 클래스를 하나 만들었다.
 구현된 TempLogicImpl 이라는 클래스를 감싸주는 TempLogicProxy라는 클래스를 만들어 주어서 그 클래스에서 TempLogicImpl을 대행하여 수행해준다.

Posted by tuning-java

AOP : Aspect Oriented Programming

관점지향 프로그래밍이다. 어플리케이션을 OOP 관점으로 모듈화하여 작성해도 다른 모듈에서 발생하는 횡단 관심을 해결하기 위한 방법이다.

횡단 관심 : 로깅 보안, 트랜젝션등 부가 기능을 의미하며,
기존의 프로그램을 최대한 수정하지 않고 원하는 부가기능을 처리하고자 하는것이다.

AOP로 구현시 핵심 모듈을 건들지 않기 때문에 재사용성과 유지보수성이 쉬워진다.

여기서 AOP의 단점은 성능에 영향을 준다는 것이다.

참고로 횡단 관심을 해결하기 위한 시점은 다음과 같다.

  1. 메소드 호출 이전 시점
  2. Exception이 발생된 시점
  3. 메소드 호출 이후 시점

여기서 시점을 point cut 이라고 하고, 포인트 컷에서 해야하는 동작을 Advice라고 한다.
point cut과 advice를 모아놓은 것을 Aspect 라고 한다.

advice의 종류

  • around advice : org.aopalliance.intercept.MethodInterceptor - 메소드 수행 전후, Exception을 모두 처리할 수 있다.
  • before advice : org.springframework.aop.MethodBeforeAdvice - 메소드 수행전 작업을 처리할 수 있다.
  • after advice : org.springframework.aop.AfterReturningAdvice - 메소드 수행후 작업을 처리할 수 있다.
  • throws advice : org.springframework.aop.ThrowsAdvice - Exception 발생시 작업을 처리할 수 있다.


결론적으로 AOP를 사용하게되면,
원하는 proxy 기반의 interceptor 를 XML 기반으로 지정할 수 있게 되고,
XML에 지정된 bean을 사용하도록 소스를 변경해 주면 proxy에서 처리하는 부분을 사용할 수 있다.

참고로 Spring 에서는 이러한 Aspect를 Java로 구현하기 위해서 다음과 같은 방법을 사용한다.
방법 1 : 스키마 기반의 구현
방법 2 : Anotation을 이용한 구현

Posted by tuning-java

IoC는 Inversion of Control 의 약자이다.
이는 프레임웍에서 클래스의 객체를 관리하는 구조라고 생각하면 된다.

IoC의 구현 방법은 DL과 DI 두가지가 있다.
DL : Dependency Lookup
DI : Dependencty Injection

DL은 JNDI를 이용하여 Lookup 하는 방식을 말하고, DI는 각 오브젝트에서 의존적인 resource나 collaborator에 대한 책임을 갖지 않고 컨테이너가 그 일을 담당하도록 하는 것이다.

DI는 다음과 같이 두가지로 나뉜다.
Setter Injection
Constructor Injection

Setter Injection은 JavaBeans의 Property 구조를 이용하며, 주로 이 방법을 사용한다. 두가지 중 어떤 방법을 사용할 지에 대해서는 개인의 취향을 따르거나, 프로젝트의 표준을 따라야 한다.


Posted by tuning-java
이클립스가 유로파로 오면서 가끔 개길때가 있다.
다음과 같은 화면이 나타나면서...
사용자 삽입 이미지

이럴때에는 batch 파일을 만들거나,
바로가기를 만들어서 다음과 같이 수정해준다.

C:\eclipse\eclipse.exe -vmargs 512m

여러가지 옵션이 있지만,
이 옵션이 가장 간단하고 편한듯
Posted by tuning-java
여기에 있는 내용은 제가 교육 받으면서 필요한 부분에 대해서 정리를 해 놓은 것 입니다.
굉장히 심도가 얕기 때문에, 자세한 내용은 책을 활용하셔야 겠지요?


Spring Framework (스프링 프레임웍) 이란건 대체 무엇일까?

스프링 프레임웍을 한마디로 표현하자면
EJB 기반으로 개발을 하지 않고 POJO(Plain Old Java Object) 기반으로 개발을 하더라도 가볍고, 제어가 가능한 상호 관련이 적은, AOP (Aspect Oriented Programming. 관점지향 프로그래밍)을 지원하고, 컨테이너를 통해 라이프사이클을 관리하고, XML 기반으로 컴포넌트를 개발할 수 있도록 지원해주는 프레임웍이라고 할 수 있다.

(한마디로 표현하자니까 이해하기도 어려울 듯 하고, 열나 길다 - -;)

스프링 프레임웍은 다음과 같은 7개의 모듈로 되어 있다.
Spring Core
Spring Context
Spring DAO
Spring ORM
Spring AOP
Spring Web
Spring Web MVC

Core : DI 라는 Dependency Injection 기능을 제공한다.
Context : 컨텍스트라는 정보를 제공하는 설정을 관리한다. JNDI, EJB, 국제화, 스케줄링이 여기에 포함된다.
DAO : DB와 관련된 JDBC 코딩 부분을 처리해 주기 위한 JDBC 추상화 레이어를 제공한다.
ORM : JDO, Hibernate, iBATIS 등 O-R Mapping API를 위한 레이어를 제공한다.
AOP : 관점지향 프로그래밍을 제공한다.
Web : 웹 기반의 여러가지 기능을 제공한다.
Web MVC : Model과 View(Web form) 사이의 구분을 제공하기 위한 관련된 기능을 제공한다.

이제 스프링 프레임웍이 어떻게 되었는지 간단히 알아보았으니,
다음에는 IoC 컨테이너 부터 천천히 알아보자.
Posted by tuning-java
윤 머시기 강사가 이야기한

Spring Framework 가 만들어진 이유

Proxy의 불편함 => AOP 의 사용
JDBC의 불편함 => Spring JDBC
Web 프로그래밍의 불편함 => Spring MVC

기타 등등의 지금까지 Java 기반의 프로젝트를 하면서 불편한 점에 대해서
보완을 하기 위해서 만들어 졌다고 한다.
Posted by tuning-java

참고로 이 설명은 [Blog2Book 자바 성능을 결정짓는 코딩 습관과 튜닝 이야기] 책을 읽는 독자분들이 부록으로 제공되는 DevPartner for Java를 보다 쉽게 사용할 수 있도록 작성되었으며, 설치시 14일간 기능의 제한이 없는 임시 라이센스가 생성됩니다.

nmshell을 이용해서 분석하기 위한 창을 띄우자. 참고로 본인은 다음과 같이 nmshell을 구동했다.

nmshell -mem -config Test

정상적으로 구동을 했다면, 다음과 같은 화면이 나타나게 될 것이다.

이제 3가지 기능중 한가지를 사용하면 된다. 제공되는 기능은 다음과 같다.

RAM Footprint : 현재 메모리에 올라와 있는 클래스의 정보를 볼 수 있다. (EJB를 많이 쓰거나 이것 저것 올라온게 많으면 서버가 맛탱이 갈 수 있으니 조심해서 사용하길 바란다.)

Object Lifetime Analysis : 임시 메모리를 어떤 클래스, 메소드, 라인에서 많이 사용했는지를 보여준다. 반드시 작업 시작전에 GC를 하는 것을 까먹지 말기 바란다.

Memory Leaks : 메모리를 릴리즈하지 않는 메모리 릭을 잡아준다. (솔직히 말하면, 쉽게 잡히진 않는다. ㅋㅋ)

이 기능 또한 설명하는데 오래걸리므로 자세한 내용은 패쑤

Posted by tuning-java

참고로 이 설명은 [Blog2Book 자바 성능을 결정짓는 코딩 습관과 튜닝 이야기] 책을 읽는 독자분들이 부록으로 제공되는 DevPartner for Java를 보다 쉽게 사용할 수 있도록 작성되었으며, 설치시 14일간 기능의 제한이 없는 임시 라이센스가 생성됩니다.

nmshell에 대해서도 봤으니, 이제 성능 프로파일링 하는 방법에 대해서 알아보자.
참고로 여기서 본인은

nmshell -perf -config Test

로 nmshell을 수행했다.

정상적으로 nmshell을 수행했다면, nmshell 창에서 해당 WAS나 어플리케이션을 시작하는 스크립트를 수행하자. 그러면 다음과 같은 화면이 나타난다.

예전에 광고에서 비트박스하는 방법을 알려주면서, 북치기 박치기만 잘하면 된다는 광고를 보았을 것이다. 그것처럼, DevPartner에서 성능 프로파일링을 하기 위해서는 두가지 버튼만 잘 누르면 된다.
그 버튼은 "Clear Collected Data" 와 "View Results" 버튼이다.

Clear Collected Data 버튼 : 지금까지 수집된 모든 데이터를 지운다.

View Result 버튼 : 지금까지 수집된 데이터를 보여준다.

쉽게 말하면, 어플리케이션을 구동하는 동안 수집된 정보는 필요가 없으므로, 화면을 수행하기 전에는 Clear Collected Data를 누른다. 그런 다음, 화면을 수행하고 나서는 View Result 버튼을 클릭하면 된다.

그러면 위와 같은 화면이 새로 나타나는데, 이제부터 수집된 데이터를 기반으로 분석을 하면 된다.

근데 책에서 몇번이고 강조를 했지만, 서버를 띄우고 나서 가장 처음 해당 화면을 수행할 때의 결과는 절대 사용하면 안된다. 잘못하면 정상적이지 못한 시스템 분석이 되기 때문에 첫번째 화면을 수행한 이후에는 반드시 Clear... 버튼을 클릭하고, 그 다음에 화면을 1회, 10회 ... 수행한 이후에 View Result 버튼을 눌러 결과를 확인하기 바란다.

결과를 확인하는 방법은 가장 어려운 부분중 하나인데, 이에 대해서는 직접 터득하시기를 권장한다. 왜냐하면, 말로 설명해도 한시간 이상 소요되는 작업이고, 아무리 말로 설명해도 이해하기가 쉽지는 않기 때문이다.

뭐 많은 분들이 원한다면 나중에 관련 내용이 추가 될 수도 있다. 

다음에는 메모리 프로파일링 하는 방법에 대해서 알아보겠다.

Posted by tuning-java

WebLogic Server Performance and Tuning
Weblogic의 성능 관련 세팅과 관련된 정보가 포함되어 있다.
http://edocs.bea.com/wls/docs92/perform/intro.html

참고로 Weblogic 8.X 이상에서 Thread 설정은 다음과 같이 한다.

Weblogic 콘솔에 로그인(보통 http://url/console 로 접근하면됨.)
-> domain 명에서 servers 를 확장후 해당 서버이름을 선택
-> Configuration 의 General tab 선택 -> 화면의 하단에 있는 Advanced의 show를 선택
-> 가장 하단의 Configure Execute Queues 를 선택
하면 Thread 관련 설정 화면으로 이동된다.

혹시 모르실 수도 있으니, DB Connection 관련 설정은 다음과 같이 한다.

Weblogic 콘솔에 로그인
-> Services 의 JDBC의 Connection Pools 에서 설정. (관련 설정이 없으면 새로 맹근다. ㅋㅋ)

Posted by tuning-java

점점 이 기능 저기능을 넣다 보면 Activity 클래스가 복잡해진다. 그 문제를 해결하기 위해서 아마도 구글에 그 똑똑하다는(? 정말?) 애들이 XML 기반의 레이아웃을 사용하는 방식을 쓴것 같다.

AndroidAPISummary 클래스에 있는 setButtons() 메소드를 다음과 같이 MainButtonManager 클래스를 만들어서 넣도록 하자.

package com.min.summary;

import android.app.AlertDialog;
import android.content.Intent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.Toast;

public class MainButtonManager {
    AndroidAPISummary parent;
    LinearLayout parentLayout;

    LayoutParams lpFillWrap=new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
    public MainButtonManager(AndroidAPISummary parent,LinearLayout  linearLayout) {
        this.parent=parent;
        parentLayout=linearLayout;
    }

    protected void setButtons() {
        Button alertButton=new Button(parent);
        alertButton.setText("Show alert");
        alertButton.setOnClickListener(new OnClickListener() {
            public void onClick(View view) {
                alertMessage("Clicked");
            }
        });
        parentLayout.addView(alertButton, lpFillWrap);

        for(int loop=0;loop<20;loop++) {
            Button but=new Button(parent);
            parentLayout.addView(but, lpFillWrap);
            but.setText("Button"+loop);
            but.setTag("Button"+loop);
            but.setOnClickListener(new OnClickListener() {
                public void onClick(View view) {
                    viewMessage("OK",Toast.LENGTH_SHORT);
                }
            });
        }
    }
    private void viewMessage(String data, int messageLength) {
        Toast t=Toast.makeText(parent,data,messageLength);
        t.show();
    }
    private void alertMessage(String data) {
        AlertDialog.show(parent, "This is a title 1", R.drawable.icon,
                "This is a message 2","Button text", true);
    }
}


여기서 중요한 것은 parent와 parentLayout이다.

이 클래스에는 this로 사용해야하는 AndroidAPISummary 객체와 버튼을 담아놓을 LinearLayout이 없기 때문에 Activity클래스에서 넘겨주어야만 한다.

그럼 바뀐 AndroidAPISummary 는 어떻게 바뀌었을까?

package com.min.summary;

import android.app.Activity;////
import android.os.Bundle;////

import android.view.Menu;
import android.view.ViewGroup.LayoutParams;
import android.widget.LinearLayout;
import android.widget.ScrollView;
public class AndroidAPISummary extends Activity {
    LinearLayout  linearLayout;
    LayoutParams lpFillWrap=new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
    MenuManager menuManager;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        ScrollView sv=new ScrollView(this);
        linearLayout=new LinearLayout(this);
        linearLayout.setOrientation(LinearLayout.VERTICAL);
        MainButtonManager mbManager=new MainButtonManager(this,linearLayout);
        mbManager.setButtons();
        sv.addView(linearLayout,lpFillWrap);
        setContentView(sv);
    }

    public boolean onCreateOptionsMenu(Menu menu) {
        boolean result = super.onCreateOptionsMenu(menu);
        menuManager=new MenuManager(menu);
        return result;
    }

}

보다 AndroidAPISummary 클래스가 간결해진 것을 확인할 수 있다.

Posted by tuning-java

이번에는 메뉴를 만들어보자.

android.view.Menu 클래스는 핸드폰에 있는 "Menu" 버튼을 클릭할 때 나타나는 메뉴를 처리하는데 사용된다.

메뉴를 추가하는 메소드는 다음과 같다.

Item  add(int group, int id, CharSequence title, Runnable callback)
Item  add(int group, int id, CharSequence title, int iconRes)
Item  add(int group, int id, int titleRes, int iconRes)
Item  add(int group, int id, CharSequence title)
Item  add(int group, int id, int titleRes)
Item  add(int group, int id, int titleRes, Runnable callback)

메뉴를 생짜베기로 Activity 클래스에 추가할 순 있지만, 개인적으로 보기에는 메뉴를 관리하는 클래스를 따로 추가하여 사용하는 것이 좋다고 생각한다.

그럼 다음과 같은 클래스를 추가해보자.

package com.min.summary;

import android.view.Menu;
import android.view.SubMenu;

public class MenuManager {
    Menu.Item menuItem1;
    Menu.Item menuItem2;
    SubMenu subMenu1_1;
    SubMenu subMenu1_2;
    SubMenu subMenu2;
    public MenuManager(Menu menu) {
        int pos=0;
        menuItem1=menu.add(0, Menu.FIRST+pos++, "Menu-1");
        menuItem2=menu.add(0, Menu.FIRST+pos++, "Menu-2");
        subMenu1_1=menu.addSubMenu(0, Menu.FIRST+pos++, "Sub menu-1_1");
        subMenu1_2=menu.addSubMenu(0, Menu.FIRST+pos++, "Sub menu-1_2");
        subMenu2=menu.addSubMenu(1, Menu.FIRST+pos++, "Sub menu-2");
    }
}

뭔지 모르시겠지만, 일단 이렇게 해보자.

그럼 이제 이 클래스를 써야겠죠?

package com.min.summary;

import android.app.Activity;////
import android.content.Intent;
import android.os.Bundle;////

import android.app.AlertDialog;

import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.LinearLayout;
import android.widget.Button;
import android.widget.ScrollView;
import android.widget.Toast;
public class AndroidAPISummary extends Activity {
    LinearLayout  linearLayout;
    LayoutParams lpFillWrap=new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
    MenuManager menuManager;
    // 중간 생략

    public boolean onCreateOptionsMenu(Menu menu) {
        boolean result = super.onCreateOptionsMenu(menu);
        menuManager=new MenuManager(menu);
        return result;
    }
    // 이하 생략
}

AndroidAPISummary 클래스의 변수로 menuManager를 만들자. 물론 해당 변수의 타입은 MenuManager 클래스이다. 
그리고 중점적으로 봐야하는 것은 onCreateOptionsMenu() 메소드이다.  위의 예와 같이 onCreateOptionMenu() 메소드를 Overridding하고, 메뉴 설정해주면 안드로이드에서 메뉴가 나타난다. 


이제 에뮬레이터를 띄워서 결과를 확인해볼까?

이제 메뉴를 클릭하면 어떤 이벤트를 처리해야 하는데, 다른 이벤트 처리방법과 비슷하다.
(솔직히 이부분은 아직 구현할 필요가 없어서 잘 모르겠다. )
나중에 시간되면 정리해야지...

Posted by tuning-java

구글 안드로이드라는 걸 공부하다보면, ddms라는걸 들어보았을 것이다.
(앞서 내가 번역한 툴들의 목록중에 ddms라는게 있다는 것을 확인할 수 있다.)

ddms를 사용하는 방법은 두가지가 있다. 이클립스에서 사용하는 것과 android의 tools 디렉토리에 있는 ddms.bat 파일을 실행하는 두가지 방법이다.

다음 그림은 이클립스에서 돌리는 화면이다.

그럼 아래의 그림은 배치파일을 실행해서 사용하는 화면이다.

여기서 굉장히 유의할 점이 있다.

나도 이거 아는데 좀 시간이 걸렸다. ㅋㅋㅋ

이클립스에서 에뮬레이터를 띄워놓고 배치파일 기반의 ddms를 돌리면 이클립스에서 콘솔이 정신을 차리지 못하면서 난리를 치기 시작할 것이다.

못믿겠으면 확인해 보기 바란다.

어느정도 힌트를 드렸으니, 한번 해결책을 찾아보세요. ㅋㅋ


다른 사용법은 나도 잘 모른다.

아직까지는 단지 화면 캡쳐용으로 사용할 뿐이다.

이클립스용에서 X 자 빨간색 표시 옆에 잘 찾아보면 메뉴가 나타나는데, 그 메뉴를 누르면 "Screen Capture"를 클릭하면 다음과 같은 화면 캡쳐 화면이 나타난다.

 

refresh를 눌러야만 현재 에뮬레이터의 화면이 나타난다는 사실을 알고 계시기 바란다.


그럼 마지막으로 이클립스에서 어떻게 하면 ddms 화면이 나타날까?

그것도 한번 여러분들이 직접 찾아 보기 바란다. ㅋㅋ

Posted by tuning-java



Blog2Book 자바 성능을 결정짓는 코딩 습관과 튜닝 이야기 책에 있는 소스 코드들이다.

혹시 잘못된 부분이 있으면 이야기해 주세요.

수정해서 올리겠습니다.

modified 2008.10.15. Because of StopWatch's Bug
Posted by tuning-java

모든 UI를 구성하는데 있어서 반드시 필요한 것은 많지만, 개발하면서 가장 필요한 것은 로그를 보는 것일 것이다. 아직까지 로그 처리를 어떻게 해야하는지는 정확하게 감이 잡히질 않는다. 하지만, 로그를 콘솔에서 보는 방법 이외에 가장 편하게 보는 것이 alert 창일 것이다.

지금까지 확인해 본 안드로이드의 메시지를 처리하는 방법은 두가지이다.

하나는 AlertDialog를 사용하는 것이고, 다른 하나는 Toast를 사용하는 것이다.

package com.min.summary;

import android.app.Activity;////
import android.content.Intent;
import android.os.Bundle;////

import android.app.AlertDialog;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.LinearLayout;
import android.widget.Button;
import android.widget.ScrollView;
import android.widget.Toast;
public class AndroidAPISummary extends Activity {
    LinearLayout  linearLayout;
    LayoutParams lpFillWrap=new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        ScrollView sv=new ScrollView(this);
        linearLayout=new LinearLayout(this);
        linearLayout.setOrientation(LinearLayout.VERTICAL);
        setButtons();
        sv.addView(linearLayout,lpFillWrap);
        setContentView(sv);
    }
    private void setButtons() {
        Button alertButton=new Button(this);
        alertButton.setText("Show alert");
        alertButton.setOnClickListener(new OnClickListener() {
            public void onClick(View view) {
               alertMessage("This is a message-2");
            }
        });
        linearLayout.addView(alertButton, lpFillWrap);
        for(int loop=0;loop<20;loop++) {
            Button but=new Button(this);
            linearLayout.addView(but, lpFillWrap);
            but.setText("Button"+loop);
            but.setTag("Button"+loop);
            but.setOnClickListener(new OnClickListener() {
                public void onClick(View view) {
                   viewMessage("OK",Toast.LENGTH_SHORT);
                }
            });
        }
    }
   

    private void alertMessage(String data) {
        AlertDialog.show(this, "This is a title", R.drawable.icon,
                data,"Button text", true);

    }

    private void viewMessage(String data, int messageLength) {
        //Toast.LENGTH_LONG
        Toast t=Toast.makeText(this,data,messageLength);
        t.show();
    }
   
}

앞에서 만들었던 AndroidAPISummary 클래스에 위와 같이 추가했다.


다른 레이아웃 설정부분과의 혼동을 피하기 위해서 버튼 설정하는 부분을 다른 메소드로 추가하였다.(setButtons() 메소드를 추가)

먼저 메시지를 처리하기에 앞서 이벤트를 처리하는 부분에 대해서 알아보자.
Button의 클릭 이벤트를 처리하기 위해서는 setOnClickListener 메소드를 사용해야만 한다. 이 메소드를 사용할때 필요한 매개변수 객체가 OnClickListener 인데, 인터페이스이므로, 이 인터페이스를 다른 클래스로 정의하거나, 위의 소스와 같이 필요할 때 구현하여야만 한다. (일반적으로 자바에서 화면단 이벤트를 처리하기 위해서는 저렇게 많이 구현해서 사용한다.)

내부적으로 정의한 OnClickListener의 내용은 프로그램이 구동될 때 수행되는 것이 아니라, 해당 이벤트가 호출되었을 때에만 구동되기 때문에, "수행하면 어쩌지?"라는 걱정은 하지 않아도 된다.


onClick 메소드는 View 객체를 받아서 처리되도록 되어 있으며, 매개변수로 받은 View는 해당 메소드에서 사용할 수 있다. 여기서 alertButton의 setOnClickListener 메소드에서는 alertMessage() 메소드를 호출했으며, 나머지 버튼들에서는 viewMessage() 메소드를 호출하도록 되어 있다.


그럼 이제 Toast와 AlertDialog에 대해서 알아보자.

Toast는 잠시 나타났다가 사라지는 메시지를 보여준다. static한 방법을 사용하면 되고, makeText() 라는 메소드에다가 메시지와 메시지를 뿌려줄 기간을 지정한다.
static  Toast  makeText(Context context, int resId, int duration)
static  Toast  makeText(Context context, CharSequence text, int duration)
duration은 Toast.LENGTH_SHORT 나 Toast.LENGTH_LONG 을 지정하면 된다.

Toast를 쓴 예제는 다음과 같다.

중간에 있는 조그만 OK 가 Toast로 띄운 메시지이다.


AlertDialog는 버튼이 있는 메시지창을 보여준다. 이것도 마찬가지로 static 한 방법으로 사용하면 되고, show() 라는 메소드에다가 여러가지 방법으로 지정하면 된다.
show()메소드의 종류는 다음과 같다.  여러분들의 입맛에 맞게 골라서 사용하기 바란다.
static  AlertDialog  show(Context context, CharSequence title, int iconId, CharSequence message, CharSequence button1Text, OnClickListener button1Listener, CharSequence button2Text, OnClickListener button2Listener, CharSequence button3Text, OnClickListener button3Listener, boolean cancelable, OnCancelListener cancelListener)

static  AlertDialog  show(Context context, CharSequence title, int iconId, CharSequence message, CharSequence buttonText, boolean cancelable)

static  AlertDialog  show(Context context, CharSequence title, int iconId, CharSequence message, CharSequence buttonText, OnClickListener buttonListener, boolean cancelable, OnCancelListener cancelListener)

static  AlertDialog  show(Context context, CharSequence title, int iconId, CharSequence message, CharSequence button1Text, OnClickListener button1Listener, CharSequence button2Text, OnClickListener button2Listener, boolean cancelable, OnCancelListener cancelListener)

static  AlertDialog  show(Context context, CharSequence title, Drawable icon, View view, CharSequence buttonText, OnClickListener buttonListener, CharSequence button2Text, OnClickListener button2Listener, CharSequence button3Text, OnClickListener button3Listener, boolean cancelable, OnCancelListener cancelListener)

static  AlertDialog  show(Context context, CharSequence title, int iconId, View view, CharSequence buttonText, OnClickListener buttonListener, CharSequence button2Text, OnClickListener button2Listener, boolean cancelable, OnCancelListener cancelListener)

static  AlertDialog  show(Context context, CharSequence title, int iconId, View view, CharSequence buttonText, OnClickListener buttonListener, CharSequence button2Text, OnClickListener button2Listener, CharSequence button3Text, OnClickListener button3Listener, boolean cancelable, OnCancelListener cancelListener)


참고로 CharSequence에는 String이나 StringBuffer, StringBuilder를 넘겨주면 되고, OnClickListener 에는 원하는 버튼의 Listener를 만들어서 그 Listener를 지정해주면 된다. 그리고, 마지막에 cancelable 이라는 boolean 값이 있는데, 그 값은 전화기의 종료버튼 위에 있는 <- 방향의 버튼을 눌렀을때 작동이 되는지 여부를 설정한다. 만약 true로 해 놓으면, 취소가 가능하다.

AlertDialog의 예는 다음과 같다.

중간에 있는 저 버튼을 포함한 box가 AlertDialog를 이용한 화면이다.

Posted by tuning-java

지금까지의 내용들은 구글 안드로이드와 함께 제공되는 문서 위주로 정리가 되었다. 하지만, 이제부터는, 본인이 직접 내 입맛에 맞게 각 API에 대해서 작성할 예정이다. 혹시 나머지 Document부분의 번역을 원하시는 분들이 많을 경우 추가로 작성할 예정이다.


이제 연습용 메인 프로젝트를 만들어 보자. 이클립스에서 New Project를 선택해서 Android Project를 만들자.

프로젝트 명은 AndroidAPISummary, 패키지 이름은 com.min.summary , 메인이 되는 액티비티 이름은 AndroidAPISummary, 그리고 안드로이드에서 아이콘에 나타나는 이름은 API Summary 로 정하자. 마지막에 있는 애플리케이션이름만 공백 사용이 가능하다.

Finish 버튼을 누르자. 그러면, HelloAndroid와 같이 여러개의 파일이 생성될 것이다.


참고로 나는 SWT, GWT, Swing등을 사용했기 때문에 화면 레이아웃을 XML로 처리하는 것에 적응이 되어 있지 않다. 대부분의 화면단 개발자 분들이 그러하듯이... 그리고, 안드로이드의 대부분 샘플들도 모두 XML로 화면처리를 했기 때문에 나는 소스에서 화면 구성하는 방법으로 정리를 하도록 하겠다.


가장 먼저 AndroidAPISummary 클래스를 열어서 다음과 같이 수정하자. 아래에 굵게 표시한 부분만 추가된 내용이다.

package com.min.summary;

import android.app.Activity;
import android.os.Bundle;
import android.view.ViewGroup.LayoutParams;
import android.widget.LinearLayout;
import android.widget.Button;

public class AndroidAPISummary extends Activity {
    LinearLayout  linearLayout;
    LayoutParams lpFillWrap=new LinearLayout.LayoutParams
        (LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
       linearLayout=new LinearLayout(this);
        linearLayout.setOrientation(LinearLayout.VERTICAL);
        for(int loop=0;loop<20;loop++) {
            Button but=new Button(this);
            linearLayout.addView(but, lpFillWrap);
            but.setText("Button"+loop);
        }
        setContentView(linearLayout);

    }
}

일단 가장 간단한 LinearLayout을 사용하였고,
LayoutParams 라는 클래스의 객체는 LinearLayout에서 View를 추가할 때 필요하기 때문에, 클래스 변수로 지정하여 재사용 하도록 했다.
onCreate() 메소드에서 linearLayout 객체를 초기화 하고, 세로 정렬하도록 setOrientation() 메소드를 사용하여 LinearLayout.VERTICAL 변수를 지정하였다.
(참고로 LinearLayout.HORIZONTAL 로 지정하면 가로로 정렬하게 된다.)
그 다음엔 for 루프를 사용해서 Button을 20개 만들어 linearLayout에 추가하였다. addView() 메소드를 사용하여 추가할 때에는 LayoutParams 로 반드시 어떻게 추가할지를 결정해야 한다. 그리고 버튼 객체에 setText() 메소드를 사용하여 버튼에 나타나는 글자를 표시하도록 했다.
마지막에는 linearLayout를 setContentView() 메소드를 사용하여 화면에 나타나도록 지정했다.

그러면 이렇게 만든 화면을 수행하면 어떻게 되는지 결과 화면을 보자.

이렇게 버튼을 20개나 만든 이유는 여러분들에게 중요한 한가지를 보여주기 위함이다. 화면이 나타난 상태에서 스크롤을 해보자.

아마 선택된 주황색 표시가 없어질 것이다.

즉 스크롤이 안된다는 의미가 된다. 그냥 이대로 사용하게 되면, 버튼들이 추가되거나, 데이터가 추가되면 스크롤이 안되는 안습상황이 발생하게 될 것이다.

그래서 필요한 것이 ScrollView 다.

package com.min.summary;

import android.app.Activity;
import android.os.Bundle;
import android.view.ViewGroup.LayoutParams;
import android.widget.LinearLayout;
import android.widget.Button;
import android.widget.ScrollView;

public class AndroidAPISummary extends Activity {
    LinearLayout  linearLayout;
    LayoutParams lpFillWrap=new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT,
        LayoutParams.WRAP_CONTENT);
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        ScrollView sv=new ScrollView(this);
        linearLayout=new LinearLayout(this);
        linearLayout.setOrientation(LinearLayout.VERTICAL);
        for(int loop=0;loop<20;loop++) {
            Button but=new Button(this);
            linearLayout.addView(but, lpFillWrap);
            but.setText("Button"+loop);
        }
       sv.addView(linearLayout,lpFillWrap);
        setContentView(sv);
    }
}

변경된 소스와 같이 ScrollView를 import하고, ScrollView를 추가하면 된다.

그럼 이렇게 했을때 결과를 보자.

이제 스크롤을 해보면 아래에 화면이 있으면 어둑어둑하게 표시가 되면서 스크롤이 부드럽게 될 것이다.

내용이 너무 많으면 지겨우니, 추가적인 내용은 다음 post에 올리도록 하겠다.

Posted by tuning-java


Workspace in use or cannot be created, choose a different one. 이라는 메시지가 나타나면서, 이클립스에서는 다른 workspace를 선택하라는 화면이 나온다.

이 경우에는 평소에 사용하는 workspace를 변경해야만 이클립스가 기동되는데, 대부분의 개발자분들이 그런 짓(?)을 하기는 싫을 것이다.


가장 쉬운 해결책
윈도우 작업 관리자를 열어서 eclipse.exe 프로세스를 죽인다.


두번째 해결책
자기가 정해놓은 workspace 디렉토리로 이동해서, .metadata 라는 디렉토리에 있는 .lock 파일을 지운다.


둘중 한 방법을 사용하면 정상적으로 이클립스가 기동된다.

Posted by tuning-java