10 Apr 2019
|
Kotlin
constructor 키워드
기본적으로 코틀린에서 클래스 생성자는 다음과 같이 클래스 선언부에서 constructor
키워드를 시용해서 만들어줍니다.
class Person constructor(name: String, age: Int)
위와 같이 클래스 선언부에서 생성자를 사용할 때는 constructor
키워드를 생략할 수 있습니다.
class Person(name: String, age: Int)
생성자를 여러 개 선언할 경우
class Person() {
constructor(name: String, age: Int) : this()
constructor(name: String) : this()
}
class Person(name: String) {
constructor(name: String, age: Int) : this(name)
}
와 같은 형태로 사용할 수 있습니다. 생성자 뒤에 this
함수 호출하는 부분은 필수입니다.
생성자 매개 변수의 기본값 설정
class Person(name: String = "default", age: Int = 0)
생성자 함수 바디
클래스에서 변수의 값 선언 외에 별도 처리가 필요한 경우는 init {}
함수를 사용해서 처리할 수 있습니다.
class Person(var name: String?, val age: Int = 0) {
init {
if (name.isNullOrEmpty()) {
name = "snowdeer"
}
}
}
생성자 매개 변수에서 val
, var
등의 선언이 생략되면 기본적으로는 val
로 인식이 됩니다.
접근 제한자
private
: 클래스 내부에서만 접근 가능
protected
: 상속받은 클래스에서만 접근 가능
internal
: 같은 모듈 안에서만 접근 가능
- 생략: 생략된경우
public
로 간주됨
09 Apr 2019
|
Android
Android에서 Protobuf를 사용하는 방법입니다.
build.gradle(프로젝트)
먼저 프로젝트의 build.gradle
에 다음과 같은 세팅을 합니다.
buildscript {
ext.protobufVersion = '0.8.6'
dependencies {
classpath "com.google.protobuf:protobuf-gradle-plugin:$protobufVersion"
}
}
build.gradle(모듈)
먼저 플러그인(plugin) 선언을 합니다.
apply plugin: 'com.google.protobuf'
그리고 build.gradle
파일 가장 아래쪽에 다음과 같은 코드를 입력합니다.
protobuf {
protoc {
artifact = 'com.google.protobuf:protoc:3.0.0'
}
plugins {
javalite {
artifact = 'com.google.protobuf:protoc-gen-javalite:3.0.0'
}
}
generateProtoTasks {
all().each { task ->
task.builtins {
remove java
}
task.plugins {
javalite {}
}
}
}
}
그리고 아래 항목도 추가합니다.
dependencies {
implementation 'com.google.protobuf:protobuf-lite:3.0.0'
}
proto 파일 정의
src/main
아래로 가보면 기본적으로 java
, res
라는 디렉토리가 존재합니다. 여기에 proto
라는 디렉토리를 하나 만들어줍니다.
그리고 샘플 proto 파일을 하나 만듭니다. 저는 snowdeer_sample.proto
라는 이름으로 만들었습니다.
Android Studio의 ProjectView에서 보기 모드가 Android
로 되어 있으면 해당 위치가 제대로 보이지 않기 때문에 Project
등으로 변경해줍시다.
snowdeer_sample.proto
syntax = "proto2";
package com.snowdeer.sample;
option java_package = "com.snowdeer.sample.proto";
option java_outer_classname = "SampleProto";
message User {
required int32 id = 1;
required string name = 2;
optional string address = 3;
enum PhoneType {
UNKNOWN = 0;
MOBILE = 1;
HOME = 2;
}
message PhoneNumber {
required string number = 1;
optional PhoneType type = 2 [default = UNKNOWN];
}
repeated PhoneNumber phoneNumbers = 4;
}
message UserList {
repeated User users = 1;
}
빌드
이제 모듈 빌드를 해봅니다. 빌드하고 나면 build/generated/source/...
디렉토리 아래에 위에서 정의한 이름(예제에서는 SampleProto
)의 Java 파일이
생성된 것을 확인할 수 있습니다.
이제 Activity에서는 다음과 같이 사용을 해볼 수 있습니다.
package com.snowdeer.protobufexample;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import com.snowdeer.sample.proto.SampleProto.User;
import com.snowdeer.sample.proto.SampleProto.User.PhoneNumber;
import com.snowdeer.sample.proto.SampleProto.User.PhoneType;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
PhoneNumber pn = PhoneNumber.newBuilder()
.setType(PhoneType.MOBILE)
.setNumber("010-1111-2222")
.build();
User user = User.newBuilder()
.setId(100)
.setName("snowdeer")
.setAddress("Seoul")
.addPhoneNumbers(pn)
.build();
Log.i("snowdeer", "[snowdeer] user: " + user.toString());
}
}
실행 결과
address: "Seoul"
id: 100
name: "snowdeer"
phone_numbers {
number: "010-1111-2222"
type: MOBILE
}
05 Apr 2019
|
Android
기본적으로 의존 라이브러리를 사용하기 위해서는 build.gradle
안에 다음과 같이 선언합니다.
dependencies {
implementation group: 'com.android.support', name: 'appcompat-v7', version: '28.0.0'
}
위와 같이 사용하거나 짧게 줄여서 group:name:version
형태로 사용할 수도 있습니다.
dependencies {
implementation 'com.android.support:appcompat-v7:28.0.0'
}
만약 항상 최신 버전의 라이브러리를 사용하고 싶을 때는 version
값에 latest.integration
을 넣으면 됩니다.
04 Apr 2019
|
Android
TimeUtil.java
import android.icu.util.Calendar;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
public class TimeUtil {
public synchronized static long getTimeAsLong() {
Calendar calendar = Calendar.getInstance();
return calendar.getTimeInMillis();
}
public synchronized static String getTimeAsString(String format) {
Date date = new Date(getTimeAsLong());
SimpleDateFormat sdf = new SimpleDateFormat(format,
Locale.getDefault());
return sdf.format(date);
}
public synchronized static Long getTimeAsLong(String format, String text) {
try {
SimpleDateFormat sdf = new SimpleDateFormat(format,
Locale.getDefault());
Date date = sdf.parse(text);
return date.getTime();
} catch (Exception e) {
e.printStackTrace();
}
return Long.valueOf(-1);
}
public synchronized static String getTimeAsString(String format, long time) {
Date date = new Date(time);
SimpleDateFormat sdf = new SimpleDateFormat(format,
Locale.getDefault());
return sdf.format(date);
}
}
Log.java
public class Log {
private static final String TAG = "ActionManager";
private static final String PREFIX = "[ram]";
public synchronized static void v(String message) {
android.util.Log.v(TAG, getDecoratedLog(message));
}
public synchronized static void d(String message) {
android.util.Log.d(TAG, getDecoratedLog(message));
}
public synchronized static void i(String message) {
android.util.Log.i(TAG, getDecoratedLog(message));
}
public synchronized static void w(String message) {
android.util.Log.w(TAG, getDecoratedLog(message));
}
public synchronized static void e(String message) {
android.util.Log.e(TAG, getDecoratedLog(message));
}
private static String getDecoratedLog(String message) {
StackTraceElement ste = Thread.currentThread().getStackTrace()[4];
StringBuilder sb = new StringBuilder();
sb.append(PREFIX);
sb.append(" [");
sb.append(TimeUtil.getTimeAsLong());
sb.append(" ");
sb.append(ste.getFileName().replace(".java", ""));
sb.append("::");
sb.append(ste.getMethodName());
sb.append("] ");
sb.append(message);
return sb.toString();
}
}
만약 Line Number까지 출력하고 싶으면 ste
변수의 getLineNumber()
메소드를 사용하면 됩니다.
02 Apr 2019
|
Android
Java
예외 처리를 위해 사용하는 try - finally
구문은 강력하긴 하지만, try
가 2개 이상 사용되거나 그 외의 이유 등으로
코드가 복잡하게 될 수 있는 단점이 있습니다.
Java 7.0 부터 지원하는 try with resources
를 사용하면 코드를 훨씬 깔끔하게 구현할 수 있습니다.
try-finally 예시
public class FileUtil {
public static String getFirstLineOfFile(String filepath) throws IOException {
BufferedReader br = new BufferedReader(new FileReader(filepath));
try {
return br.readLine();
} finally {
br.close();
}
}
}
2개 이상의 try가 사용될 경우
public class FileUtil {
private static final int BUFFER_SIZE = 1024;
public static void copy(String src, String dest) throws IOException {
InputStream in = new FileInputStream(src);
try {
OutputStream out = new FileOutputStream(dest);
try {
byte[] buf = new byte[BUFFER_SIZE];
int n;
while ((n = in.read(buf)) >= 0) {
out.write(buf, 0, n);
}
} finally {
out.close();
}
} finally {
in.close();
}
}
}
try-with-resources 예제
public class FileUtil {
private static final int BUFFER_SIZE = 1024;
public static String getFirstLineOfFile(String filepath) throws IOException {
try (BufferedReader br = new BufferedReader(new FileReader(filepath))) {
return br.readLine();
}
}
public static void copy(String src, String dest) throws IOException {
try (InputStream in = new FileInputStream(src);
OutputStream out = new FileOutputStream(dest);) {
byte[] buf = new byte[BUFFER_SIZE];
int n;
while ((n = in.read(buf)) >= 0) {
out.write(buf, 0, n);
}
}
}
}
catch 사용 예제
public static String getFirstLineOfFile(String filepath) {
try (BufferedReader br = new BufferedReader(new FileReader(filepath))) {
return br.readLine();
}
catch (IOException e) {
e.printStackTrace();
return "";
}
}