이진수 표현

숫자 앞에 "0b" 또는 "0B" 를 붙여 이진수 표현이 가능합니다.
int hex = 0x8;  // 16진수
int dec = 8;  // 10진수
int oct = 08; // 8진수
int bin = 0b101010; // 2진수

숫자 사이에 언더스코어(_)표시

숫자 사이에 언더스코어(_)를 넣을 수 있게 되어 가독성을 향상시킬 수 있게 되었습니다.
long creditCardNumber = 1234_5678_9012_3456L;
long socialSecurityNumber = 999_99_9999L;
float pi = 3.14_15F;
long hexBytes = 0xFF_EC_DE_5E;
long hexWords = 0xCAFE_BABE;
long maxLong = 0x7fff_ffff_ffff_ffffL;
byte nybbles = 0b0010_0101;
long bytes = 0b11010010_01101001_10010100_10010010;

switch 구문에서 String 사용

그동안 switch 구문에 기본형과 열거형만 사용할 수 있었고 String 을 사용할때는 다수의 if else 문으로 제어문을 구성해야 했다면 Java 7 부터는 switch 구문에서 String 을 사용할 수 있게 되었습니다.
public String getTypeOfDayWithSwitchStatement(String dayOfWeekArg) {
  String typeOfDay;
  switch (dayOfWeekArg) {
    case "Monday":
      typeOfDay = "Start of work week";
      break;
    case "Tuesday":
      case "Wednesday":
      case "Thursday":
        typeOfDay = "Midweek";
        break;
      case "Friday":
        typeOfDay = "End of work week";
        break;
      case "Saturday":
      case "Sunday":
        typeOfDay = "Weekend";
        break;
      default:
        throw new IllegalArgumentException("Invalid day of the week: " + dayOfWeekArg);
  }
  return typeOfDay;
}

다이아몬드(<>)

제네릭 인스턴스를 생성할 때 그동안 인스턴스 선언/생성 양쪽에 모두 타입을 적어주었어야 했었습니다.
Map<String, List<String>> myMap = new HashMap<String, List<String>>();
다이아몬드 기호(<>) 표시만으로 인스턴스 생성 부분에서의 타입을 생략할 수 있게 되었습니다.
Map<String, List<String>> myMap = new HashMap<>();

try-with-resources (Api level 19)

그동안 사용 후 close() 메서드를 호출하여 자원을 반납해야 했던 InputStream/OutputStream 등은 Java 7 에서 try 구문 시작시 간단한 선언으로 자동으로 자원반납이 가능하게 되었습니다.
static String readFirstLineFromFileWithFinallyBlock(String path) throws IOException {
  BufferedReader br = new BufferedReader(new FileReader(path));
  try {
    return br.readLine();
  } finally {
    if (br != null) br.close();
  }
}
Java 7 이전까지는 이렇게 BufferedReader 를 사용하고 난 후 finlly 에서 close() 를 호출해 stream 을 닫아주어야 했었다면 아래 코드와 같이 try 구문이 시작할 때 BufferedReader 선언하면 try 구문이 끝날 때 자동으로 close() 를 호출하게 됩니다.
static String readFirstLineFromFile(String path) throws IOException {
  try (BufferedReader br = new BufferedReader(new FileReader(path))) {
    return br.readLine();
  }
}
주의: AutoCloseable interface 에 의한 close() 호출이기 때문에 Api level 19(Kitkat) 버전부터 사용할 수 있습니다.

multi-catch Exception

그동안 예외를 처리할 때 서로 다른 예외간 처리방식은 동일함에도 불구하고 같은 내용의 코드를 중복 작성해야 하는 불편함이 있었습니다.
catch (IOException ex) {
    logger.log(ex);
    throw ex;
catch (SQLException ex) {
    logger.log(ex);
    throw ex;
}
Java 7 에서는 '|' 연산자로 여러개의 예외를 한번에 묶어 처리할 수 있게되었습니다.
catch (IOException|SQLException ex) {
  logger.log(ex);
  throw ex;
}

참고 사이트

디자인 가이드라인에는 마법 같고, 생활을 편리하게 만들어 주며, 사용자에게 놀라운(좋은쪽으로 말입니다) 경험을 선사해 주기 위해 주목할 원칙과 바로 적용할 수 있는 디자인 패턴들이 잘 정리되어 있습니다. 특히 “확인받기와 알려주기" 항목을 살펴보시면, 안드로이드 UX 의 고전적인 질문 - “언제 다이얼로그 창을 표시해야 할까?” 에 관한 참고할만할 내용을 살펴보실 수 있습니다. 

확인받기와 알려주기


확인받기 는 사용자에게 지금 막 수행되려는 작업을 정말로 수행할 것인지 다시 한번 물어보는 것 입니다. 앞으로 일어날 일을 보다 자세히 설명하고 주의할 점이 있는 경우 이를 경고 할 수 있습니다. 알려주기 는 해당 작업이 성공적으로 수행되었음을 텍스트로 표시해 주는 것 입니다. 시각적 혹은 그 외 다른 명확한 피드백이 없는 작업의 경우, 알려주기 패턴을 이용해 구체적인 피드백을 제공할 수 있고, 필요한 경우 진행된 작업을 취소할 수 있는 기능도 함께 제공할 수도 있습니다.

두 가지 방식을 잘 활용하면, 사용자가 되돌릴 수 없는 실수를 하는 것을 방지하고, 좀 더 명료하고 사용하기 편리한 경험을 제공할 수 있습니다. 물론, 앱 내의 
모든 작업에 대해 사용자의 확인을 받거나 알려주기 패턴을 적용해야하는 것은 아닙니다.아래의 플로우 차트를 참고해서 적용여부를 한번 고민해 보시면 좋을 것 같습니다.


이해를 돕기 위해, 실제 앱에서 확인받기와 살펴보기 패턴이 사용된 경우를 직접 살펴보도록 하겠습니다.

확인받기가 필요한 경우 - Play 북



플레이 라이브러리에서 책을 삭제하면, 사용자의 다른 어떤 디바이스에서도 해당 책의 내용을 확인 할 수 없게 됩니다. 이런 경우 되돌릴 수 없는 손실이 발생할 수 있기 때문에, 앱은 경고 창을 통해 사용자의 확인을 받아야 합니다. 경고 창을 디자인 할 때는 제목에 지금 일어날 작업 내용을 다시 한번 명시해서 사용자가 현재 어떤 작업이 이루어지는지 명확히 알 수 있도록 강조할 필요가 있습니다.

확인받기가 필요없는 경우 - 안드로이드 빔



안드로이드 빔을 통해 컨텐츠를 공유하고자 할 때는 ‘확인받기' 패턴을 사용할 필요가 없습니다. 컨텐츠 공유는 안드로이드 빔으로 두 디바이스가 연결된 후, 공유할 컨텐츠(사진)을 터치 해야만 이루어집니다. 만일 컨텐츠 공유를 취소하고 싶을 때는 그저 두 디바이스를 다시 멀찍히 떨어뜨려 놓으면 됩니다.

알려주기가 필요한 경우 - Gmail 임시 저장



사용자가 메일 작성 화면에서 백 혹은 업 네비게이션을 통해현재 화면에서 벗어나는 경우, 작성중이던 메일 내용이 자동으로 저장됩니다. 이 작업에 대한 명시적인 사용자 피드백이 없기 때문에 알려주기 패턴이 사용되며, Gmail 은 토스트를 통해 이 사실을 알려줍니다. 단, 취소하기 기능은 제공되지 않는데, 임시 저장은 앱에서 자동으로 이루어진 것이며 작성 중이던 메일 내용은 임시 보관함에서 쉽게 확인할 수 있기 때문입니다.

알려주기와 되돌리기가 필요한 경우 - Gmail 대화 삭제



사용자가 Gmail 에서 대화 목록 중 하나를 삭제한 경우에는, 앱은 ‘알려주기' 패턴을 이용해 사용자에게 이를 알리고, 동시에 되돌리기 버튼을 표시해 줍니다. 이 알림창은 사용자가 다른 액션 (대화 목록을 스크롤 하는 등의)을 수행하기 전까진 화면 상에 남아있게 됩니다.

확인받기나 알려주기가 필요 없는 경우


+1 하기

사용자 확인을 받을 필요가 없습니다. 사용자가 +1 을 눌렀다고 큰 사고가 발생하는 경우는 별로 없고,  실수인 경우 +1 버튼을 다시 한번 누르면 결과를 금방 되돌릴 수 있습니다. 알려주기 기능 또한 필요가 없습니다. +1 버튼을 누르면 멋진 애니매이션 피드백이 주어지고, 버튼의 색상이 붉게 변경됩니다. 추가적인 피드백은 불필요합니다.

홈스크린에서 앱 바로가기 삭제하기

사용자 확인을 다시 받을 필요가 없습니다. 홈 스크린에서 앱 바로가기 아이콘을 삭제하기 위해서는 앱 아이콘을 끌고 화면 상단의 정해진 목적지로 가져가야 합니다. 사용자의 의도가 분명히 들어난 셈이고 실수로 이런일이 벌어질 가능성은 거의 없습니다. 혹시, 실수로 일어난 일이라도 이를 되돌리는 데는 몇 초 시간이 걸리지 않습니다. 또, 홈 스크린에서 앱을 드래그 한 그 순간 이미 홈 스크린에서 앱 아이콘이 없어지기 때문에 알려주기 패턴을 사용할 필요도 없습니다.

사용자가 작업을 수행하려고 할 때, 상황에 맞추어 ‘확인받기' 와 ‘알려주기' 두 가지 패턴을 적절히 사용하면, 사용자의 혼란을 줄이고 좀 더 편안하게 앱을 사용할 수 있도록 도울 수 있습니다. 이 두 가지 패턴을 포함하여 안드로이드 디자인 가이드라인에서 제공된 다양한 디자인 패턴을 잘 활용하여, 마법같은 사용자 경험을 제공하는 멋진 안드로이드 앱을 만나보길 기대하고 있겠습니다.


이 변경 사항은 킷캣에 대응하는 모든 안드로이드 호환 디바이스에서 동일하게 적용되는 원칙임으로 첫번째 외부 저장소 외에 추가적인 외부 저장소를 활용하는 앱을 개발하는 개발자 분들은 꼭 내용을 확인하시길 바랍니다. 이외에 킷캣에서 변경된 부분에 관한 보다 자세한 내용은 안드로이드 개발자 사이트의 4.4 API 중요 변경 사항 항목을 참고해 보시기 바랍니다. 또는 관련된 내용을 한글로 정리해주신 전슬마로님의 블로그 포스트를 참고하셔도 큰 도움이 될 것 같습니다.



동영상에서 설명드린 것 처럼, 이 새로운 웹뷰는 안드로이드 4.4 이상 버전에는 모두 기본으로 탑재되며, 기존 앱들도 별다른 수정 없이 새로운 웹뷰의 혜택을 바로 누릴 수 있습니다. 다만, 몇 가지 기존과 동작 방식이 변경된 부분이 있어 이를 다시 한번 정리해 보았습니다.
  • 웹뷰의 기본 USER_AGENT 값에 크롬 버전이 포함되도록 변경되었습니다. 예를 들어 다음과 같습니다.
    • Mozilla/5.0 (Linux; Android 4.4; Nexus 4 Build/KRT16H) AppleWebKit/537.36(KHTML, like Gecko) Version/4.0 Chrome/30.0.0.0 Mobile Safari/537.36
  • 다른 View 와 마찬가지로, UI 스레드가 아닌 곳에서 loadData 등의 메서드를 통해 웹뷰의 내용을 변경할 수 없습니다.
  • 비동기 자바 스크립트 함수 호출등을 이유로 UI 스레드를 블락해선 안됩니다. 대신, 자바스크립트 함수 호출의 결과를 받아 볼 수 있는 evaluateJavascript() 메서드가 추가되었습니다.
  • 사용자가 URL 을 클릭하는 이벤트를 오버라이드 하여 원하는 작업을 수행하고자 하는 경우, 사용자 정의 URL 은 RFC 3986 표준에 의거한 유효한 URL 을 사용해야 합니다. 그렇지 않은 경우 shouldOverrideUrlLoading() 메서드가 호출 되지 않거나, 의도하지 않은 형태의 URL 로 변경된 결과를 받게될 수 있습니다.
  • Viewport 메타태그에 다음과 같은 변화가 있습니다.
    • target-densitydpi 속성을 지원하지 않습니다.
    • 뷰포트의 크기를 디바이스 화면 크기보다 작게 설정하면, 해당 값이 화면 크기로 재설정되는 대신 화면크기에 맞도록 뷰포트가 확대됩니다.
    • 뷰포트 태그를 여러번 선언한 경우 가장 마지막에 사용된 태그만 적용됩니다.
  • CSS 스타일 관련되어 다음과 같은 변화가 있습니다.
    • 스타일 속성으로 background 을 지정하는 경우 background-size 속성 값이 오버라이드 됩니다. 따라서, 특정한 background-size 속성을 지정하기 위해서는 우선 background 속성 값을 지정한 다음에 background-size 속성을 설정해야 합니다.
    • window.outerWidth 와 window.outerHeight 같은 속성들은 실제 스크린 픽셀 값 대신 CSS 픽셀 값을 반환합니다.
    • NARROW_COLUMNS 와 SINGLE_COLUMN 값이 더이상 지원되지 않습니다. 이 값들은 targetSdkVersion을 18이나 그 이하로 설정할 경우에도 동작하지 않습니다.
  • 자바스크립트로 웹뷰 상의 터치 이벤트를 직접 처리할 때는, touchcancel 이벤트를 처리해야 합니다. touchcancel 이벤트는 특정 HTML 요소가 선택된 후 페이지 스크롤이 일어나거나, event.preventDefault() 가 호출되지 않은 경우 발생합니다.
보다 자세한 내용은 안드로이드 개발자 사이트의 웹뷰 마이그레이션에 관한 가이드라인 문서를 참고해 보시기 바랍니다. 혹은, 전슬마로님이 한글로 정리해주신 내용도 참고해 보시면 좋을 것 같습니다. (감사의 댓글도 잊지 마세요~)
https://medium.com/marojuns-android/407facd301c7

새롭게 구현된 킷캣 버전의 새로운 웹뷰와 편리한 개발자 도구를 이용하여 여러분의 웹컨텐츠를 안드로이드 위에서 더욱 멋지게 활용하시길 바랍니다.