0.티스토리 코드블럭
option command ,
1. ip 확인하는 방법
ipconfig getifaddr en0
0.티스토리 코드블럭
option command ,
1. ip 확인하는 방법
ipconfig getifaddr en0
현재 서비스 중인 테블릿에서 도는 앱을 점주들이, 컨트롤 타워에서 끄기를 원하는 요구사항이 들어왔다.
일단 system에 접근하여 shut down을 하기위해서는
제조사의 플랫폼키 가 필요하다
해당 내용으로 사이닝을 하지않으면, permission denied 가 난다.
app/build.gradle 에서
로 빌드해준다.
브릿지를 태워야 하기에
DeviceOffModule.java 와 DeviceOffPackage.java 를 만들어준다.
DeviceOffModule.java
DeviceOffPackage.java
해당 package를 mainapplication.java 에서 임포트해주고
react native 에서
로 실행해주면 된다.
AndroidMainfest.xml 에
까지 추가하면,
해당 앱이 설치된 기기의 전원을 언제든지 끌수 있다.
[ React Native ] Memory Leak / Memory 초기 사용량 낮추기 (0) | 2024.12.18 |
---|---|
[ React Native ] Android debugging Deep dive ! (2) | 2024.11.30 |
[ React Native ] Dynamic splash screen by url (서버에서 받아오는 URL 로 스플래시 스크린 세팅하기 ) (1) | 2024.09.05 |
[ React Native ] Dynamic splash screen 적용하기 (0) | 2024.08.12 |
[ React Native ] Kakao login 중 pod install 시 CDN: trunk URL couldn't be downloaded 발생 (0) | 2024.05.02 |
현재 회사에서 서비스하고있는 앱은 회사에서 설치한 테블릿에서만 도는 앱이다.
테블릿은 4GB 램을 사용중이다.
대부분의 사용자가 일주일에 한번씩은 앱을 종료하였지만,
앱을 설치하고 한번도 앱을 종료하지 않은 매장에서 memory leak 으로 인한 다운이 발생하여 해결하게 되었다.
다른 일반 앱들과는 다르게, 상점별 세팅 / Van사의 앱 프로토콜 / 수백개의 메뉴이미지로, 초기 메모리가 350MB 정도 되었다.
GC 가 돌긴하였지만, 30분만에 300메가 정도가 늘어난 것으로 관찰된다.
최종 개선된 버전을 보면, 초기메모리가 243MB 로 낮아졌을뿐만아니라, 메모리가 260~290MB 로 유지되는것을 확인할수있었다.
해당 개선을 하였던 방법을 포스팅하고자한다.
당면과제는 두가지였다.
1.초기의 메모리값을 낮춘다.
2.앱을 켜놓아도 메모리값을 적정수준으로 유지한다.
해당 과제중
1.초기 메모리값을 낮추기 위해
-Hermes 엔진 활성화
-ABI 분리 (arm64-v8a 로만 빌드)
-번들 크기 최적화 (package.json에서 사용하지 않는 패키지를 제거)
-이미지관리 최적화(동적 이미지 FastImage)
-이미지관리 최적화 (아이콘 svg 사용)
해당 작업을 하였다.
해당 작업이후의 메모리사용량을 보면,
일단 초기 메모리 사이즈가 많이 감소된것을 관찰할수있다.
두번째 작업은
-이미지관리 최적화 (정적 이미지 용량절감) : png 리소스 webp 로 변경
였다. 리소스들 자체를 webp 로 변경하니
해당 리소스의 크기가 줄어든만큼 초기 메모리 사용량이 줄어든 것을 확인하였다.
세전째 작업은
-Proguard/R8 관련 작업이었다.
해당 작업은 난독화와 관련되어 메모리와 크게 상관이 없을줄 알았는데
해당 내용 작업후, 4MB정도의 감소폭을 확인 할 수 있었다.
앱의 특성상 초기 메모리를 더욱 낮출수는 없다고 판단하여
이제 Memory Leak 관련된 작업을 시작했다.
해당 메모리 누수가 일어나는 부분은 '광고'화면 이 주를 이뤘다.
처음 작업은
1.interval 조건추가
2.backgroundImage key 추가
3.debug 로그제거
4.fastimage key 추가
5.lazy video 로직 변경
6.arm64 만 빌드되도록 수정
7.mmkv 패키지 삭제
8.안쓰는 import 제거 / lodash partial import
이었는데,
대표적인 memory leak 이 일어나는 interval 함수 사용의 로직을 개선하였다.
Native / Others 쪽 메모리가 쌓이는것을 보고 backgroundImage / FastImage 에 key 값을 추가하여, unmount 되는것을 확실히하였고,
filesystem을 이용하는 debug로그와, video 쪽을 손봤다.
소스코드를 정리하면서 package 쪽을 정리하니
초기 메모리 사용량은 비슷하지만, 기하급수적으로 메모리 쌓이는 부분이 해결되는 것을 확인했다.
두하지만, 여전히 300MB 를 넘는 사용량을 보이기에
FastImage 쪽 Glide 의 cache 컨트롤 쪽을 개선하였다.
- 메모리 캐시 크기 지정 : 20MB
- 이미지 Bitmap 처리 포맷 변경 : RGB565 사용하도록 설정
해당 작업이후
최종적인 메모리 사용량은 안정적으로 되었고,
해당 문제가 발생했던 매장에 설치하여 모니터링중이다.
[ React Native ] android device 전원끄기 (1) | 2024.12.20 |
---|---|
[ React Native ] Android debugging Deep dive ! (2) | 2024.11.30 |
[ React Native ] Dynamic splash screen by url (서버에서 받아오는 URL 로 스플래시 스크린 세팅하기 ) (1) | 2024.09.05 |
[ React Native ] Dynamic splash screen 적용하기 (0) | 2024.08.12 |
[ React Native ] Kakao login 중 pod install 시 CDN: trunk URL couldn't be downloaded 발생 (0) | 2024.05.02 |
이번 회사 프로젝트에 오래 걸린 디버깅이 있어서 까먹기전(?)에 정리를 해놓는다.
현재 회사에서 담당하고 있는 프로젝트는 React-Native 로 되어있지만, 특정 테블릿(안드로이드)에만 설치가 되어 제공을 하기에, 철저히 안드로이드 관련된 내용이라
Android와 관련된 공부를 하게되어 기쁘다.
현재 코드푸쉬를 할때마다 1500대정도 꾸준히 업데이트를 성실히 따라오고 있는데, 유독 한 매장에서 자꾸 '앱이 종료된다' 라는 CS가 들어왔다.
당연히 ANR 은 치명적인 오류이기에, 즉각 대응에 나섰다.
일단 지금 서비스에는 data dog / google crashlytic 가 붙어있다.
해당 증상이 발생했다는 날에 정보를 확인해봐도 2600개의 세션중에 crash report 는 없었다.
물론 google crashlytics 도 마찬가지였다.
data dog 의 내부로직은 모르지만, google crashlytics은 MainActivity.java의 UncaughtExceptionHandler 를 오버라이딩해서 사용하고있다.
그러면 해당 에러는 해당 핸들러에 안걸리는 이유로 '앱이 종료된다'고 유추하였다.
해당 핸들러에 안걸리는 가장 큰 이유중의 하나는 '메모리'문제이다.
따라서 해당 매장의 환경(광고대기화면)과 동일한 환경으로 세팅을하여 일주일정도 메모리 사용량을 확인하였다.
adb 로 테블릿을 무선으로 연결한후, adb top 이라는 터미널 명령어로 메모리트래킹을 했는데, 메모리가 점점 쌓이는 현상은 발견되지 않았다.
지금까지 개발을 하면서, 앱이 비정상종료가 되었는데, 아무 이유를 파악할 수 없는 경우는 처음이었다.
CS에서 들어도, 유저가 액션을 하다가 뻗거나, 기능 동작중에 앱이 내려가는 경우가 아니라, 테블릿을 켜놓고 다음날쯤에 꺼지는 경우는 재연이 쉽지가 않았다.
결국 안드로이드 시스템 로그를 확인해보기로 했다.
해당 테블릿을 사용하고 있는 사용자에게 방문하여
adb 로 해당 테이블에 무선연결 후, adb bugreport 로 시스템 로그를 받아왔다.
ApplicationExitInfo 클래스 덕분에 해당 로그에서 우리 앱이 언제 어떻게 왜 종료되었는지 확인을 할 수가있다.
https://developer.android.com/reference/android/app/ApplicationExitInfo
해당 클래스 설명에서 보면, 자세한 원인이 나와있다.
우리의 원인은 13 으로, 안드로이드 문서를 보면
not by problems in apps and not actionable by apps 라고 나와있다.
'앱문제는 아니고, 앱의 액션문제도 아니야'
하지만...고객이 불편하다고 생각하기에 해당 문제를 해결해야한다.
따라서 getDescription 을 통해 자세한 subreason을 확인하기로했다.
this process had been in empty state for a long time;
직역하면, '이 프로세스는 empty state 에 너무 오래있었다' 이다.
안드로이드의 프로세스는
https://developer.android.com/guide/components/processes-and-threads?hl=ko
https://developer.android.com/guide/components/activities/process-lifecycle?hl=ko
에서 확인할 수 있듯이
foreground > visible > service > cached (empty)
로 나뉜다.
가장 하위 단계의 프로세스에서 너무 오래떠있어서 종료하니까, 우리앱의 프로세스를 높여볼까?
라는 생각으로,
foreground service 를 띄워봤다.
라이브러리를 사용하여 쉽게, 앱이 실행중일때 포그라운드 서비스를 띄워놀수 있게되었다. 해당 포그라운드 서비스는 안드로이드 프로세스의 두번째인 visible process 에 해당한다.
하지만 해당 증상은 계속되었고,
이번에는 WorkManager를 적용하여
java쪽에서
DeviceEventManagerModule.RCTDeviceEventEmitter
네이티브 이벤트를 한시간마다 한번씩 발생해줬고,
를 통해 로그를 찍어놓았다.
이번기회에, 안드로이드의 시스템로그를 보는것과 전반적인 안드로이드의 프로세스에 대해 조금 더 알게되어 기분이 좋다.
[ React Native ] android device 전원끄기 (1) | 2024.12.20 |
---|---|
[ React Native ] Memory Leak / Memory 초기 사용량 낮추기 (0) | 2024.12.18 |
[ React Native ] Dynamic splash screen by url (서버에서 받아오는 URL 로 스플래시 스크린 세팅하기 ) (1) | 2024.09.05 |
[ React Native ] Dynamic splash screen 적용하기 (0) | 2024.08.12 |
[ React Native ] Kakao login 중 pod install 시 CDN: trunk URL couldn't be downloaded 발생 (0) | 2024.05.02 |
지금 프로젝트에서 구분자를 받아와서 해당 구분자로 기존 리소스를 스플래시로 띄우는 것을 구현해놓았다.
https://liveforownhappiness.tistory.com/138
기획쪽에서, 스플래시 스크린의 교체를 요청해왔는데,
초기에 스플래시 스크린의 구분자와 리소스가 바뀔확률이 0에 가깝다고 개발을 구분자와 리소스로 해놓았는데
앞으로도 해당 교체가 있을것 같아서
서버에서 url 을 받아와 구현하는 것으로 변경했다.
일단 서버에서 url을 받아온뒤, 해당 url을 splash 스크린에서 세팅해주도록 변경하였다.
일단 전에 작업되어있던
(위에 링크 게시물 참고)
에 웹 리소스 uri 값을 native 쪽으로 내려줬다.
SplashScreen.java 코드를
이렇게 수정해주었다.
기존 image view 에 .setImageURI(Uri.parse(uri)) 값으로 리소스를 세팅해주니
resolveUri failed on bad bitmap uri
라는 에러가 나와
해당 작업중 inputstream.에 url content() 를 담아 Drawble 로 생성했다.
해당과정에서 통신은 새로운 Thread 에서 돌려야하기때문에 new Thread 로 새로운 쓰레드를 만들어줬고
또한 UI 업데이트는 메인쓰레드에서만 하기때문에, runOnUiThread 로 imageView 업데이트를 진행했다.
이제 서버에서 이미지링크를 내려주면 해당 이미지로 스플래시를 세팅하여 보여주고 앱이 실행된다.
[ React Native ] Memory Leak / Memory 초기 사용량 낮추기 (0) | 2024.12.18 |
---|---|
[ React Native ] Android debugging Deep dive ! (2) | 2024.11.30 |
[ React Native ] Dynamic splash screen 적용하기 (0) | 2024.08.12 |
[ React Native ] Kakao login 중 pod install 시 CDN: trunk URL couldn't be downloaded 발생 (0) | 2024.05.02 |
[ React Native ] react-query 에러 : bad argument type. starting with v5 only the object. (0) | 2024.04.04 |
현재 맡은 프로젝트가 테이블에 들어가는 앱인데,
해당 앱은 제조사가 모두 본인들의 splash screen 을 사용하고 싶어했다.
여러 라이브러리를 찾아보던중, 그냥 기존에 쓰던 splash screen 을 patch-package 해서 사용하기로했다.
SplashScreen.java
해당 java 중 show function 을 수정했다.
기본 앱이 react native 이기때문에, 안드로이드와 가장 가볍게 쓸수있는 데이터 저장소를 SharedPreference 로 정하고,
api 로 받아온 스플래시 스크린의 구분자를 SharedPreference 로 저장해주고,
해당 값에 따라
show 해주는 식으로 작성했다.
서버에서 데이터 값을 받아와서 브릿지를 통해 안드로이드의 SharedPreference에 저장하는 방법은
해당 방법으로 해결했으며
android 의 sharedPreference 에 접근하는 방법은
RNHaredPreferencesPagkage.java
RNSharedPreferencesModul.java
로 작성했고
const { RNSharedPreferences } = NativeModules;
로 해결했다.
yarn add @react-native-seoul/kakao-login
사이드 프로젝트에 카카오 로그인을 붙이는데
[!] CDN: trunk URL couldn't be downloaded: https://cdn.jsdelivr.net/cocoa/Specs/a/d/6/KakaoSDKCommon/2.22.1/KakaoSDKCommon.podspec.json Response: SSL peer certificate or SSH remote key was not OK
해당 에러가 나왔다.
찾아보니, vpn을 사용하라는 디투어가있었는데...해당 방법은 적합한것 같지않아서
다른 방법을 찾았다.
pod file 상단에
를 추가해주고,
podfile.lock 을 삭제해준다.
터미널에서
root/ios 로 이동하여
pod repo remove trunk
로 레포를 제거하고
pod install
로 다시 깔아주면
잘 해결된다.
현재 redux로 앱내의 상태를 관리하는데,
react-query 를 이용하여, 클라이언트 / 서버의 상태를 분리하기위해 이번에 react-query 를 도입하려한다.
const {data, isSuccess, isError} = useQuery(['get-main-info'], () => getMain);
해당 코드로 query 를 사용하려하니
해당 에러가 나왔다.
에러를 읽어보면 reqct-query v5부터는 object type으로 변경되었다고하는데
const {data, isSuccess, isError} = useQuery({
queryKey: ['get-main-info'],
queryFn: getMain,
});
같은 내용을 해당 코드로 변경해서 해결했다.
rn을 하다보면, 기본적인 틀을 짤때 하는 일들이 있다.
1.stack navigation / bottom tab navigation
2.redux toolkit
3.persist-store
4.eslint / prettier 설정
등등...
사실 프로젝트를 시작할때, 기본적인 구조를 고민하면서 짜는건 즐거운 순간이지만, 대부분 고민을 하고나서 짜는 구조는 비슷해보인다.
해서, 시간이 날때 기본적인 라이브러리들을 넣고, 폴더 구조를 잡아 놓은 프로젝트를 만들었다.
이번에 새로 시작하는 프로젝트에 해당 프로젝트의 이름만 변경하여 이용하려고한다.
그러기위해서는 일단, 프로젝트의 이름 / 번들 id 등을 변경해줘야한다.
그러기 위해서는
npm install -g react-native-rename
명령어로, react-native-rename 라이브러리를 설치해준다.
또 기존 템플릿에서 브랜치도 하나 따준다(혹시 문제가 생길경우를 대비하여, 나는 작업할때 모두 브랜치를 딴다)
git checkout -b rename
후에, 해당 브랜치의 로컬에서
react-native-rename "새로운이름"
명령어를 쳐주면,
파일들이 변경된다.
루트에서
npx pod-install
로 다시 pod 세팅을 해주면 ios 는 모두 변경이 완료된다.
안드로이드 같은 경우에는
기존 번들 아이디를 검색하여, 새로운 번들아이디를 입력하면되고, xcode에서도 같은 번들아이디로 변경해주면 끝난다.
해당 브랜치의 루트에서
rm -rf ./.git
로 깃파일을 없애주고
git init
으로 새로운 깃을 만들어 레파지토리에 연결해주면 끝이다.
깃 레파지토리를 옮길때, 두가지 방법이 있다.
1.commit 유지하지않는방법
2.commit / branch 를 유지하는 방법
당연히 2번이 훨씬더 편한다.
해당 레파지토리의 .git 파일을 삭제하고,
git init 으로 새로 등록하여 git push 를 하면 끝나기때문이다.
하지만, 후임자와 팀원들을 위해 commit 내용을 공유해주어야 할 필요가 있다.
만약 해당깃에
터미널에서
1. git clone --bare {복사하고자하는저장소의 git 주소, 원래 소스코드가 있는 레파지토리}
2. cd {복사하고자하는저장소의git 주소}
3. git push --mirror {붙여놓을저장소의git주소}
만 하면 끝난다.
하지만, 100mb 가 넘는경우, 해당 프로세스를 진행하면 100mb 가 넘는 파일이 있기때문에 에러가 난다.
해결하기 위해서는
1. 100mb 이상의 파일처리
brew install git-lfs
brew install bfg
를 먼저깔아주고
1. git clone --bare {복사하고자하는저장소의 git 주소, 원래 소스코드가 있는 레파지토리}
2. cd {복사하고자하는저장소의git 주소}
3. git filter-branch --tree-filter 'git lfs track "*.{zip,jar}"' -- --all
4. brew install bfg 로 깔지않고 jar 파일을 받았을때, bfg의 위치를 넣은 path
java -jar {bfg의 위치를 넣은 path } --convert-to-git-lfs '*.zip'
java -jar {bfg의 위치를 넣은 path } --convert-to-git-lfs '*.jar'
5. git push --mirror {붙여놓을저장소의git주소}
하면 끝