onCreate 함수를 사용하면서 Bundle 이 뭘까 하는 생각은 많이 해보았지만 막상 찾아본적은 없었다. 그래서 찾아보았다.


Bundle은 Key-Value의 쌍으로 이루어진 일종의 해쉬맵 자료형이다.


이 Bundle은 여러 상황에서 유용하게 사용될 수 있다.


1. 액티비티 간의 데이터 전달


Intent를 사용하여 액티비티끼리 데이터를 교환할 수 있는데, 만약 넘길 데이터가 있다면 URI 형식이나 putExtras() 함수를 이용한다.


그러나 객체 같은 경우 위와는 다른 방법을 필요로 한다. 이 때 Bundle을 사용한다.


처음에는 일부 글만 보고 Bundle에서는 parcelable만 지원하는줄 알았는데 serializable도 지원한다. 자세한 함수에 대해서는 공식 문서를 참조하자.

(객체 직렬화에 대해서는 다른 글에서 자세히 다룰 것이다)


어쨌든 Bundle이라는 자료형을 Intent에 넣어 데이터를 다른 액티비티에게 전달할 수 있다.


2. 어플리케이션의 이전 상태 저장


onCreate 함수를 선언할 때 볼 수 있는 Bundle savedInstance라는 매개변수가 바로 이것을 위해 존재하는 것이다.


보통 메모리가 부족하거나 화면이 가로, 세로 전환되었을 때 ShutDown 된다. 


이런 경우 앱을 다시 실행했을 때 기존의 데이터는 다 날라가게 되는데, 만약 중요한 데이터를 입력 또는 저장 중이었다면 큰 낭패일 것이다. 그래서 Bundle을 이용해 값을 저장할 수 있다.


onSaveInstanceState 와 onRestoreInstanceState 함수를 오버라이딩해서 값을 저장하고 보관한 데이터를 불러올 수 있다.



참고


Android Bundle Class


[안드로이드] Activity,Fragment 에서 Bundle 로 Object, ArrayList 넘기기


Bundle(번들)이란?


Parcelable을 사용한 오브젝트 전달 (Object serialization using Parcelable)


[ANDROID] 안드로이드 BUNDLE

'안드로이드' 카테고리의 다른 글

안드로이드 리소스 ID  (0) 2017.11.27
serializable, parcelable  (0) 2017.11.24
안드로이드 Deprecated  (0) 2017.11.23
FLAG_ACTIVITY_NEW_TASK  (0) 2017.11.23
안드로이드 Intent, Task  (0) 2017.11.22
블로그 이미지

NCookie

,

PWM이란

임베디드/개념 2017. 11. 24. 00:34

PWM(Pulse Width Modulation)


펄스의 폭을 컨트롤하기 위한 제어방법이다. 


펄스의 폭을 조절하여 전력의 크기를 조절할 수 있다.


이전에 포스팅했던 스위칭 레귤레이터에서 전압을 변환하는 원리를 생각하면 된다.


펄스 주기에서 On 되어있는 비율을 duty라고 하며, duty 값이 낮을수록 출력 전압은 낮아진다.


이를 이용해 디지털 전압으로 아날로그 전압을 공급할 수 있다.

(아두이노에서는 analogWrite라는 함수를 이용하여 아날로그 전압을 출력할 수 있는데, 이 때 pwm이 사용된다.)



참고


기본기::PWM


PWM(Pulse Width Modulation) 펄스 폭 제어 란 무엇인가


'임베디드 > 개념' 카테고리의 다른 글

JTAG  (0) 2018.01.02
개념 정리 목록  (0) 2018.01.02
레귤레이터(Regulator)  (0) 2017.10.25
수동소자, 능동소자  (0) 2017.10.25
전압, 전류, 저항  (0) 2017.10.25
블로그 이미지

NCookie

,


Nordic의 DFU 라이브러리에서 설정값을 가져오는데, 'SETTINGS_NUMBER_OF_PACKETS' is deprecated 라면서 해당 상수에 가로줄이 그어졌다. 


찾아보니 이 deprecated 는 안드로이드 버전이 업그레이드 되면서 다른 것으로 대체된 경우, 지원이 끊긴 경우 등에서 발생한다.


deprecated가 되었어도 계속 지원을 해주는 경우도 있다고는 하지만, 가장 좋은 방법은 현재 디바이스의 버전을 확인하여 그에 따라 호환성을 제공하는 것이다.


지금 문제가 되는 DFU 라이브러리에서 상수가 정의된 부분을 찾아보았더니, 


This constant is now deprecated. Please, use {@link DfuServiceInitiator#setPacketsReceiptNotificationsValue(int)} to set it.

라고 한다. 


Nordic의 github에 있는 nRF-Toolbox의 코드(공식 어플이다)를 보면, 다음과 같이 설정한다. 

final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
final SharedPreferences.Editor editor = preferences.edit();
final boolean keepBond = preferences.getBoolean(SettingsFragment.SETTINGS_KEEP_BOND, false);
final boolean forceDfu = preferences.getBoolean(SettingsFragment.SETTINGS_ASSUME_DFU_NODE, false);
final boolean enablePRNs = preferences.getBoolean(SettingsFragment.SETTINGS_PACKET_RECEIPT_NOTIFICATION_ENABLED,
                                                Build.VERSION.SDK_INT < Build.VERSION_CODES.M);
String value = preferences.getString(SettingsFragment.SETTINGS_NUMBER_OF_PACKETS,
                                            String.valueOf(DfuServiceInitiator.DEFAULT_PRN_VALUE));

int numberOfPackets;
try {
    numberOfPackets = Integer.parseInt(value);
} catch (final NumberFormatException e) {
    numberOfPackets = DfuServiceInitiator.DEFAULT_PRN_VALUE;
}

final DfuServiceInitiator starter = new DfuServiceInitiator(mSelectedDevice.getAddress())
        .setDeviceName(mSelectedDevice.getName())
        .setKeepBond(keepBond)
        .setForceDfu(forceDfu)
        .setPacketsReceiptNotificationsEnabled(enablePRNs)
        .setPacketsReceiptNotificationsValue(numberOfPackets)
        .setUnsafeExperimentalButtonlessServiceInSecureDfuEnabled(true);
 


SETTINGS_PACKET_RECEIPT_NOTIFICATION_ENABLED 상수의 경우, DfuSettingsConstants.java 파일에 "settings_packet_receipt_notification_enabled" 라는 문자열로 저장되어 있다. 그래서 자동으로 defValue인 false가 enablePRNs라는 변수에 들어가게 되는 것이고.


참고로 SharedPreference란 UI에 대한 간단한 정보들을 저장할 수 있는 임시 저장소 같은 공간이다. 여기에 저장된 값들은 화면이 전환되었을 때 이전 값을 다시 세팅해주는 등을 하는데에 사용될 수 있다.



참고


[안드로이드] Deprecated 되는건 기준이 뭐죠?


안드로이드 deprecated

'안드로이드' 카테고리의 다른 글

serializable, parcelable  (0) 2017.11.24
안드로이드 Bundle  (0) 2017.11.24
FLAG_ACTIVITY_NEW_TASK  (0) 2017.11.23
안드로이드 Intent, Task  (0) 2017.11.22
마시멜로우 권한 요청 시 [화면 오버레이 감지됨] 발생  (0) 2017.11.20
블로그 이미지

NCookie

,

이전 글에서 설명했던 Intent Flag와 관련된 내용이다.



Activity Affinity


먼저 Activity Affinity라는 개념이 있는데, 액티비티와 태스크를 관리하기 위해 사용한다.


기본적으로 AndroidManifest의 package 명으로 설정되어 있다.


보통 같은 어플리케이션의 액티비티들은 같은 affinity를 가지고 있고 하나의 태스크에서 관리하게 된다.



FLAG_ACTIVITY_NEW_TASK


새 액티비티는 기본적으로 자신을 호출한 액티비티와 같은 태스크에서 관리가 된다.


이 때 FLAG_ACTIVITY_NEW_TASK라는 플래그를 사용하면 새로운 태스크 또는 같은 Affinity를 가지는 태스크로 가게 된다.


만약 FLAG_ACTIVITY_MULTIPLE_TASK 플래그와 함께 사용하면 무조건 새로운 태스크를 생성한다.



예시


앱 A에 액티비티 A1, 앱 B에 액티비티 B1, B2가 존재한다고 하자.


Case 1) 앱 A 실행 후 A1에서 B1 호출


B1은 A1과 같은 태스크에서 관리가 된다.


따라서 B1에서 Back을 하면 A1이 나타난다.


TASK1 : A1 - B1



Case 2) 앱 A 실행 후 A1에서 B1 호출 + FLAG_ACTIVITY_NEW_TASK


B1과 같은 affinity를 가지고 있는 태스크가 현재 존재하지 않기 때문에 태스크를 새로 생성하고 B1은 그 태스크의 Root Activity가 된다.


TASK1 : A1

TASK2 : B1



Case 3) 앱 A, B 실행 후 A1에서 B2 호출 + FLAG_ACTIVITY_NEW_TASK


(이 때 앱 B를 실행하였기 때문에 B1은 TASK3 이라는 태스크에 존재한다)


B2와 같은 Affinity를 가진 태스크가 존재한다.


B2는 B1과 같은 태스크에서 관리되고, B2에서 Back을 했을 때 B1이 보여지게 된다.


TASK1 : A1

TASK3 : B1 - B2



참고


[Android] Activity 생성시에 사용되는 Intent Flag 정리


Activity Affinity, FLAG_ACTIVITY_NEW_TASK

블로그 이미지

NCookie

,

안드로이드 시스템에서 컴포넌트 간의 호출과 메시지 전달에 사용된다.


인텐트를 통해 화면을 전환하거나 값을 전달할 수 있다.


호출될 대상을 명시하냐 아니냐에 따라 명시적 인텐트(Explicit Intent)와 암시적 인텐트(Implicit Intent)로 나누어진다.


명시적 인텐트(Explicit Intent)


말 그대로 호출될 컴포넌트를 명시한다.


만약 호출한 컴포넌트가 반환된 뒤 값을 받아오고 싶다면, startActivity() 대신에 startActivityForResult()를 사용한다. 그 후, 콜백 함수인 onActivityResult()를 오버라이드하여 반환된 값을 사용할 수 있다.


암시적 인텐트(Implicit Intent)


호출할 컴포넌트를 명시하지 않는 대신, 호출 대상 컴포넌트의 속성을 정의한다.


여기에는 Action, Category, Tpye 등이 있다.


Action은 말 그대로 호출된 컴포넌트가 수행할 동작이고, Category는 이 Action을 좀 더 보충해주는 설명이라고 보면 된다.


컴포넌트가 처리하기를 원하는 데이터들은 주소록, 사진, 텍스트 등 여러 종류가 있는데, 이는 Type에서 정의된다. 이 때 전달되는 데이터는 URI 형식으로 정의되어 있으며, 주소를 전달한다.


이 외에 직접 전달할 데이터가 있다면 putExtra() 등을 사용하면 된다.



Intent Filter


암시적 인텐트를 사용할 때 적용되며, AndroidManifest의 intent-filter라는 태그 내에서 정의할 수 있다. 


사용되는 필터로는 action, category, data, type 등이 있다. 



Task(Activity Stack)


인텐트를 사용하여 다른 액티비티들을 호출하다가, 다시 Back 키를 누르면 이전에 사용했던 액티비티들이 보인다. 이는 Task 라는 곳에 스택 형식으로 액티비티가 쌓이기 때문이다.


이러한 Task는 메모리 상에 여러 개가 존재할 수 있으며 서로 독립적이다.


가장 아래에 있는 액티비티를 Root Activity라고 하며, 가장 상단에 있는 액티비티가 현재 사용자와 상호작용하고 있는 액티비티이다.


이렇게 순차적으로 쌓이는(stack) Task에서, 순서를 바꾸거나 제어 등을 하고 싶다면 Intent 객체에서 Flag를 설정하면 된다.



Flag


이 Flag를 사용하여 Task 내 액티비티의 흐름을 제어할 수 있다. AndroidManifest나 소스 코드에서 직접 설정할 수 있다.


Flag에는 여러 종류가 있으며, 자세한 내용은 알아서 찾아보자. 엄청 많다.



참고


- 인텐트(Intent)란 무엇인가?

- 어플리케이션 컴포넌트의 실행 : 인텐트(Intent)


- 내가 누군지 말해줘! - 인텐트 필터(Intent Filter)


- 액티비티와 태스크(Task)


[Android] Activity 생성시에 사용되는 Intent Flag 정리

안드로이드 Intent Flag 정리(Activity 관리)

블로그 이미지

NCookie

,