기술 블로그 만들기 - Github-pages, Hexo

1. 노션을 사용하는 것에 대한 불편함

(1) 노션의 단점

  • 읽기 어려운 URL + 제목을 수정하면 같이 변경되는 URL

    → 해보니 Hexo도 비슷한 이슈가 있음. 하지만 노션이 공유하기 어려운 것도 사실임.. 블로그로서 만들기가 어려움.

  • 페이지 로딩이 느림

    → Hexo는 기본적으로 정적사이트를 생성해주기 때문에 이 부분은 해결이 됨.

    정적 웹사이트란, 서버에서 배포하기 전까지는 이미 올려진 데이터만을 보여주기 때문에 페이지 내에서 글 수정이 불가능하며 그렇기 때문에 가볍다는 장점이 있다. 페이지를 로드한 후에는 서버와 통신할 필요가 없으니까.

덧붙여,

(2) 대체 플랫폼

  • Notion + Cloudflare

  • Tistory

  • Velog

  • Github-pages

    → 내가 지금까지 해본 건 Tistory/Notion(오직 노션)/Github(레포지토리를 DB 삼아 md 파일 만듦. 사이트를 따로 생성하지 않음.)/Jekyll(페이지 껍데기만 만듦)/OneNote/EverNote 였다.

    그 중 고유한 Url을 생성할 수 있고 디자인을 코드단으로 만질 수 있는 Jekyll이 제일 재밌었는데 그래서 Github-pages를 사용하기로 함.

    단, Jekyll은 제외하고.(왠지 한 번 만들고 실패해서 손이 안 감.)

(3) Github-pages 적용에 필요한 것

  • 정적 사이트 생성기(Static Site Generator): Jekyll(ruby), Hugo(Go), Hexo(Node.js), Gatsby 등
    • 정적 웹 사이트 생성기: DB 통신 등을 해서 서버에서 HTML 페이지를 실시간으로 만들던 동적 사이트 방식이 아닌, 완성된 HTML 파일을 바로 전달.

고민은 길지 않았다. 서버 문외한인 내가 가장 많이 들어본 Node.js 기반 Hexo를 사용하기로 결정했다.

(4) Hexo 적용 후 불편했던 점

하는 김에 hexo를 이용하면서 불편했던 점도 적어봄. 위에 나열된 노션의 단점은 모두 커버되었으나 일부 사용하기 어려운 점이 있었다.

  • 페이지를 업데이트하려면 코드를 수정해서 배포해야하기 때문에 바로 수정된 걸 볼 수 없다.(hexo에서 제공하는 draft 기능을 사용하는 데에도 동일한 문제있음)

    → 노션의 이용을 병행하여 draft(초안)은 노션에 작성하기로 함. (일단 나는 편해짐.)

  • 여러 PC에서 배포를 할 수 있는 수월한 방법을 찾지 못함.

    • 방법(링크)은 찾았는데 기존 .deploy_git을 다른 PC에 동기화해줘야(동일하게 옮겨줘야) 하는 번거로움때문에 시도 안 하는 중..
    • Github에 올린 코드를 받아서 hexo-cli만 설치하여 올리려고 보니 hexo server 명령어가 기능을 잘 안 하고(기존 작업하던 PC OS는 윈도우, 새로 시도한 PC는 맥), 커밋 안 한 다른 PC에서 수정하던 게 마음에 걸려서 골치아파지더라.
  • 목차 생성 시 h1 아래에 h2가 아닌 h3으로 하위헤더를 바로 생성할 경우, 아래 이미지와 같이 일부가 생략된다.

(5) 노션의 장점

노션의 이용을 병행하려고 보니 장점을 빼놓을 수가 없다.

  • 접근성이 좋다. 웹, 앱 어디서든 편집할 수 있다.

  • 동기화가 잘 된다. 엄청 잘 된다! 처음 노션을 고른 이유가 동기화였다.

  • 편리한 단축키. ctrl + x로 한 행을 삭제하거나 슬래시(/)로 페이지를 만들 수 있게 하거나 여러가지로 잘 사용중.

  • 편집이 편하고 예쁘다! (잘 쓰진 않지만 수정된 내용은 히스토리로 남아서 혹시모를 상황에 대비가 가능하다.)

    • 드래그앤드랍으로 행 옮기거나 블록처리 가능한 점.
    • 어디서든 특정 부분을 하이라이트 하기 좋음. md는 코드 내에서는 볼드체가 불가능하거나 불편한 점이 있음. 이것도 따로 방법을 찾아봐야 할듯.
    • 폰트가 읽기 좋음. md는 바꾸기 귀찮아서 디폴트로 사용중인데 영어는 거의 잘 나오는데 PC에서 한국어가 픽셀 깨지듯이(예민) 나옴.
    • 헤더를 만들었을 때 딱 읽기 좋은 형태로(상하단 여백, 텍스트 강조) 노출됨. md는 가끔 h1 쓰는데도 읽으면서 가독성 떨어져서 일일이 bold 넣어줘야함.

2. Hexo 환경설정

(1) node.js 및 npm 버전 확인

내 경우 React.js 시작하기 에서 node.js와 npm이 설치된 상태여서 Hexo에 필요한 버전만 확인했다.

  • Mac에서 node.js 및 npm설치 homebrew는 Mac에서 패키지 관리를 용이하게 하기 위한 툴이다. 이걸 먼저 설치.
    1
    /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
    그리고 node.js를 설치하면 npm도 함께 설치되기 때문에 아래 명령어로 node.js를 설치.
    1
    brew install node
1
2
3
4
> node -v
v14.15.5
> npm -v
6.14.11

Hexo를 사용하기 위해서는 node.js는 v12이상을 권하고 있다.(최소 v10.13)

(2) Hexo 설치

1
> npm install -g hexo-cli

(3) Hexo 초기화

1
> hexo init testBlog

위 명령어로 초기화하면 아래와 같은 파일구조로 기본 설정파일들이 생성된다.

(4) 파일구조

1
2
3
4
5
6
7
8
.
├── _config.yml
├── package.json
├── scaffolds
├── source
| ├── _drafts
| └── _posts
└── themes
  • _config.yml: 환경설정(사이트 설정;웹사이트 제목, URL 설정, include 설정 등 가능)
  • package.json: 데이터 파일. EJS, Stylus, Markdown 렌더러들은 기본으로 설치됨.
  • scaffolds: 새 포스트/페이지를 생성했을 때 기본으로 만들어질 레이아웃을 정의.

(5) 명령어

  • 서버 실행: hexo s (server)
  • 정적파일 생성: hexo g (generate, public/이 생성된다.)
  • 배포: hexo d (deploy)
  • 생성 및 배포: hexo d -g (hexo deploy -generate)
  • 클린: hexo clean (public/이 삭제된다.)

커맨드라인에서 hexo clean을 하게되면 마지막 INFO에 아래와 같이 뜨는 것을 볼 수 있다. 즉, DB와 public 폴더가 초기화된다.

1
2
3
INFO  === Registering Hexo extensions ===
INFO Deleted database.
INFO Deleted public folder.

3. 커스텀

(1) 사이드바

_config.icarus.yml 편집

4. 포스팅 - 이카루스 테마(icarus theme) 사용

(1) 새 포스트 생성

흔히 알고 있는 하나의 포스팅을 쓸 때 사용한다.

1
hexo new post "title"

(2) 이미지 폴더 생성

주의
1. 파일명은 대소구분을 한다. “png”와 “PNG”는 다르다.
2. 아래 방법으로 하게되면 hexo clean 명령어 사용 시 public/아래의 파일은 날아가므로 여기에 파일을 넣지 않도록 할 것.
  1. _config.yml에서 post_asset_folder 속성을 true로 바꾼다.

  2. 포스트 생성 시(hexo new post) 포스트의 제목과 같은 폴더가 자동으로 생성될텐데 여기에 이미지 파일을 넣는다.

  3. 이렇게 되면 ![](/2022/02/04/006-create-personal-blog-with-githubpages-and-hexo/006-02.png)와 같이 접근할 수 있다.
    내 경우 _config.yml에서 permalink를 “:year/:month/:day/:title/“로 해두어 저렇게 나온다.

주의
![](./image01.png)처럼 상대경로를 사용하게되면 포스팅을 클릭하여 나타난 페이지에서는 정상적으로 이미지가 노출되나 사이드메뉴의 카테고리 중 하나를 클릭했을 때 페이지에서 상대경로가 맞지 않아 이미지가 깨지게 된다.

(3) 새 페이지 생성

페이지는 생성할 경우 해당 페이지명으로 된 폴더와 하위에 index.html 파일이 생성되며 포스트와 다르게 상단 탭에 연결할 수 있는 것으로 보임. 따라서 category와 tag는 사용할 수 없고 about처럼 상단에 추가할 수 있다.

1
hexo new page "page"

(4) Scaffolds(머리말) 속성

  • title 대괄호가 잘 안 들어가서 이스케이프문자를 넣어야하나했는데 그냥 큰따옴표로 묶어서 해결해버림.
  • date 내가 지정해주지 않아도 자동으로 DB에 발행일이 들어가는가 보더라. 딱히 그럴 일이 없어서 이게 수정이 되는지는 확인 안해봄.
  • categories, tags categories, tags는 여러개 지정할 수 있는데, 다음과 같이 두 가지 방법이 있다.
    1
    2
    3
    4
    categories:
    - ctg1
    - ctg2
    tags: [tag1, tag2]

(5) toc 띄우기

이카루스 default 테마에서는 toc 속성이 false로 되어있는지 처음에는 나타나지 않으나 아래와 같이 true로 명시해주면 바로 [카탈로그]라고 뜬다. 사이드에 위치하는데 position 옵션에서 left/right를 지정할 수 있다.

창의 너비가 작아지면 우선적으로 보이는게 left라서 나는 left로 해두고 left sidebar의 sticky 옵션을 true로 바꾸었다.

1
2
3
4
5
6
7
8
toc: true
widgets:
-
position: left
type: toc
index: true
collapsed: true
depth: 3

(6) 로컬 테스트

http://localhost:4000/에서 확인한다.

로컬 테스트는 배포 전 로컬의 파일 변경만으로 확인할 수 있는데, 아래 케이스에 해당한다.

  • configuration이 변경된 경우
    • 서버를 내렸다가(ctrl + C) 다시 올려야(hexo s) 적용이 된다.

로컬에서 테스트가 끝나면 아래 명령어로 배포 후 1-2분 후 적용되었는지 https://dl137584.github.io/에서 확인할 수 있다.

1
hexo d -g

(7) about 페이지 생성

1
hexo new page about

(public에 about 폴더를 만들고 별짓을 다했는데 그냥 new page하면 되는 거였어..)

page 명이 “about”인 이유는 _config.icarus.yml에서 navbar:menu:About에 설정한 이름을 따라간 것.

1
2
3
4
5
6
7
8
9
# Page top navigation bar configurations
navbar:
# Navigation menu items
menu:
Home: /
Archives: /archives
# Categories: /categories
# Tags: /tags
About: /about

(8) 초안 작성

1
hexo new draft title

이렇게 생성된 포스트는 _posts/가 아닌 _draft/에 위치하게 된다. 작성은 했는데 바로 배포하고 싶을 때 md 파일을 _draft 폴더로 옮기면 배포해도 포스팅이 노출되지 않기 때문에 편하게 쓸 수 있다.

만약 테스트 시 draft 파일도 보이도록 하고자한다면 서버를 올릴 때 –draft 옵션을 붙여주면 된다.

1
hexo server --draft

5. 마크다운 활용

노션의 callout(설명) 구현

인용과 차이를 두면서 노션의 callout UI와 같이 일부영역 강조를 편하게 사용하고 싶어서 마크다운의 테이블 구조를 활용하여 아래와 같이 만들었다. 인용 외에 참고사항 등에 사용할 예정이다.

Title
Contents1
Contents2

좌우 여백은 위의 경우 제법 넓게 나타나는 편인데, 가운데 영역(Title, Content1, Content2)의 총 너비가 짧아서 그렇다. Title이나 Content의 길이가 길어질 경우 여기에서 사용한 것처럼 여백이 줄어들게 된다.

마크다운 코드는 아래와 같이 사용하였다.

1
2
3
4
5
  | Title |  
--- | --- | ---
| Contents1 |
| Contents2 |
| |

[번역: Async Basics with Rust] 동시성 VS 병렬성(Concurrent vs Parallel)

이 포스팅은 Async Basics with Rust의 글을 번역한 것입니다. 오역, 의역, 생략이 있으니 감안하여 읽어주십시오.

동시성과 병렬성의 차이는 무엇인가?

이 주제에 대해 곧바로 동시성이 무엇인지 정의함으로써 파헤쳐보자. 병렬 상의 동시성과 쉽게 헷갈릴 수 있어서 시작부터 두 가지를 명확히 구분해둘 것이다.

동시 실행(Concurrency)이란 동시에 많은 것을 **처리하는** 걸 말한다.

병행(Parallelism)이란 동시에 많은 일을 **수행하는** 걸 말한다.

우리는 멀티태스킹을 동시에 여러 개의 작업을 진행한다는 개념으로 쓴다. 이러한 다중 작업에는 두 가지 방법이 있다.

하나는 작업을 동시에(;함께; 겸임) 진행하지만, 실제 같은 시간에 하지는 않는 것이며,

그림1 - Concurrent

또 다른 방법은 병렬적으로 실제 같은 시간에 여러 작업을 진행하는 것이다.

그림2 - Parallel

몇 가지를 정의해보자.

  • 리소스(Resource)

    작업을 진행하는 데에 필요한 것. 리소스는 제한되어있다.

    한 예로 CPU의 시간이나 메모리를 들 수 있다.

  • 작업(Task)

    진행하면서 어떤 종류의 리소스를 필요로하는 기능 집합(A set of operations)이다.

    하나의 작업은 몇 개의 sub-operations로 구성된다.

  • 병렬성(Parallel)

    정확히 같은 시간에 독립적으로 일어나는 일.

  • 동시성(Concurrent)

    동시에 진행중(in progress)인 작업들을 말하지만, 반드시 같은 시간에 진행되는 것은 아니다.

    이는 중요한 차이점이다. 만약 두 작업이 동시에 실행됐지만 병렬적이지는 않을 때, 그 작업들은 stop(멈춤)하거나 resume(재시작)할 수 있어야 한다.

주석 > 왜냐하면 병렬적이지 않은 것은 위의 [그림2 - Parallel]과 같이 한 작업이 계속해서 CPU를 붙잡고 항상 진행중 상태에 있지 않기 때문이다. 멈추고 재시작하기를 반복한다.

따라서 동시 실행 속성을 가지고 있다면 interruptable(끼어들 수 있는)하다고 말한다.

내가 사용하는 심상모형(mental model)

나는 우리가 병렬성이나 동시성을 가진 프로그램을 만들 떄 어려워하는 이유가 일상에서 일어나는 사건들을 모델링하는 방법에서 기인한다고 생각한다. 우리는 대게 잘못된 직관으로 대략적인 정의를 내리는 경향이 있기 때문이다.

concurrent의 사전적 정의는 parallel과의 차이를 인지하는 데에 도움을 주지 않는다.

나로 말할 것 같으면, 병렬성과 동시성의 차이점이 필요한지를 떠올린 게 시작이었다.

이들이 필요한 이유는 리소스의 활용도와 효율성과 관련된 모든 것에 있다.

효율성이란 어떤 일을 하면서, 또는 바라는 결과를 내는 데에 쓰이는 자원, 에너지, 노력, 돈, 그리고 시간을 낭비하지 않는 (대게 측정할 수 있는) 능력을 말한다.

  • 병행(Parallelism)

    작업을 수행하면서 리소스를 계속해서 늘린다. 이는 효율성을 고려하지 않는다.

  • 동시 실행(Concurrency)

    효율성과 리소스 활용도 모두를 고려한다. 동시 진행은 절대 단 하나의 작업을 더 빠르게 만들 수는 없다. 대신 리소스를 더 효율적으로 운용하고, 그럼으로써 작업들의 집합(a set of tasks)이 더 빠르게 끝나도록 한다.

경제학에서 몇 가지 유사점을 찾아보자.

상품 제조 사업에서는 린(LEAN)이 대표적이다.

린 이라는 기술을 사용함에 있어 가장 이점은 기다리는 시간과 가치없는 작업을 제거하는 것이다.

프로그래밍에서 말할 것 같으면, blocking과 polling을 피한다고 말할 수 있다.

동시성 및 I/O와의 관계

지금까지 말한 걸 보면, 비동기 코드를 작성하는 데 리소스를 최적으로 사용할 때야 비로소 의미가 있다.

프로그램을 짤 때 동시성이 도움이 되지 않는 경우도 있다. 병렬로 작업할 파트들로 나눌 수 있다면 더 많은 리소스를 할당하는 식으로 문제를 해결할 수 있다.

동시성에 관한 두 가지 주요 이용 사례가 있다:

  1. 입출력이 수행되는 중에 일부 외부 이벤트가 발생할 때까지 기다리는 상황.
  2. 여러 가지에 집중해야할 때 한 가지에만 너무 오래 기다리는 걸 방지해야하는 상황.

첫 번째는 기본적인 입출력 예제이다: 당신이 한 가지 작업을 진행하기 전에 네트워크 호출이나 DB 쿼리 등이 발생할 때까지 기다려야하는 상황이다. 그러나 지금 다른 할 일도 많기 때문에 다른 작업을 계속하다가 작업(네트워크 호출 등)이 준비가 됐는지 정기적으로 확인하거나 준비가 됐을 떄 알림을 받아야 한다.

두 번째는 UI 단에서 자주 일어나는 일이다. 당신이 한 개의 코어만 가지고 있다고 하자. 그럼 CPU에서 집중적으로 작업을 수행하고 있는데 대체 어떤 UI가 무반응을 피할 수 있을까?

음, 당신이 지금 하고 있는 작업이 뭐든간에 멈추고, “UI 갱신”을 하고, 그 후에 하려고 했던 일을 재시작할 수도 있다. 이렇게하면 작업을 1초에 60번 중지/재시작 해야한다. 그러면 당신은 결국 대략 60Hz의 새로고침 빈도를 반응하는 UI를 가지게 될 것이다.

OS에서 제공하는 스레드에 관하여

I/O 처리 전략에 관해 이야기하면서 스레드에 대해 좀 더 다룰 거지만 여기서도 언급하겠다. OS 스레드를 사용할 때 한 가지 문제는 코어에 매핑되는 것처럼 보인다는 것이다. 대부분의 운영 체제가 스레드 수가 코어 수와 같을 때까지 하나의 스레드를 하나의 코어에 매핑하려고 시도하더라도 이게 반드시 올바른 심상 모델은 아니다.

코어보다 많은 스레드를 생성하면, OS는 스레드간에 스위치를 수행하고 각 스레드에 실행시간을 제공하는 스케줄러를 사용하여 각 스레드를 동시에 진행하도록 할 것이다. 그리고 시스템에서 프로그램은 겨우 하나만 실행되지 않는다는 걸 명심해야한다. 다른 프로그램도 여러 개의 스레드를 생성할 수 있고, 이는 CPU에 있는 코어보다 더 많은 스레드가 있음을 의미한다.

그러므로, 스레드는 병렬적으로 작업을 수행하도록 하는 수단이 된다. 이는 동시성을 달성하는 수단이기도 하다.

이건 동시성에 관한 마지막 파트로 이어진다. 이제 일종의 참조 프레임을 정의해야 한다.

참조 프레임 바꾸기

당신의 관점에서 봤을 때 완벽하게 동기적인 코드를 짰다고 하자. 잠시 멈춰서 운영 체제 관점에서 이게 어떻게 보일지 생각해봐라.

운영 체제는 당신의 코드를 처음부터 끝까지 실행하지 않을 수 있다. 매순간 프로세스를 멈추고 다시 시작하길 반복할 것이다. CPU는 당신이 보기에 이 작업에만 집중하고 있다고 생각하는 동안에도 멈추고 일부 입력을 처리하고 있을지도 모른다.

그러니 동기적 실행은 그저 환상이다. 하지만 프로그래머로서 당신의 관점에서, 그렇지만도 않다. 이게 요점이다:

다른 맥락 없이 동시성을 말할 때, 당신은 프로그래머이며 당신의 코드는 참조 프레임이 된다. 만약 이를 염두에 두지 않고 동시성에 대해 이해하려한다면 혼란스러울 수 있다.

즉, 참조 프레임을 염두에 둬야 한다.

아직 복잡하게 들릴 수 있다. 이후 비동기 코드와 함께 작업하면서 이를 계속 상기해낸다면 복잡함은 점점 덜게 될 것이라 약속한다.

[Android] Glide에서 비트맵 이미지가 GC되는 과정

개요

위의 공식 문서에서 나와있는 바와 같이 기본적으로 Glide로 비트맵을 관리하는 걸 추천하고 있다.

이를 관리해줘야 하는 이유는 다음과 같다.

앱에서 대량의 비트맵 데이터를 표시하면 OutOfMemoryError 오류가 발생할 수 있습니다.

OutOfMemory 오류를 방지하기 위하여 안드로이드에서는 recycle() 기능을 제공하는데, 이 메소드를 실행하면 비트맵에 사용한 메모리를 회수할 수 있다. 즉, 이 메소드를 호출함으로써 해당 비트맵은 GC의 대상이 된다. 당연히 해당 비트맵을 더이상 사용하지 않을 거라고 확정된 시점에 호출해야한다.

Glide는 비트맵의 메모리를 어떻게 관리하고 있는가?

메모리 캐시 vs 디스크 캐시 의 내용에 따르면 비트맵 캐싱은 LruCache를 사용하는 대표적인 예다. 여기서 힌트를 얻어서 Glide를 적용하면서 설정했던 BitmapPool 사이즈 디폴트값을 보자. 관련 코드는 다음과 같다.

1
2
3
// 비트맵 풀: The default size is based on the screen size and density of the device
int bitmapPoolSizeBytes = 1024 * 1024 * 30; // 30mb
builder.setBitmapPool(new LruBitmapPool(bitmapPoolSizeBytes));

BitmapPool 사이즈는 단말의 스크린사이즈와 density 값에 따라 달라진다고 나와있다.

Glide에서 비트맵의 라이프사이클 링크

Glide에서 비트맵을 관리하는 데에 있어 일반적인 생명주기는 다음과 같다.

InputStream -> Bitmap -> View -> Memory Cache -> Bitmap Pool -> Recycle

해당 링크 해석본

비트맵은 메모리 캐시 또는 BitmapPool에서 View(또는 target) 및 Loop로 이동할 수도 있습니다. 디코딩 파이프 라인 (예 : 변환을 통해) 중에 리소스를 수동으로 재활용하는 경우 비트맵이 표시되지 않고 recycled state가 될 수도 있습니다. 그렇지 않으면 비트맵이 크기 제약으로 인해 제거될 때 메모리 캐시에서 BitmapPool로, BitmapPool에서 recycled state로 이동합니다.

“Cannot obtain size for recycled Bitmap” 오류는 Recycle state에 도달한 비트맵을 그리려고 할 때 발생합니다. 결코 발생해서는 안되지만 다음과 같은 몇 가지 시나리오에서 발생할 수 있습니다.

  1. 변환 중에 디코딩 프로세스 중에 비트맵을 수동으로 recycle할 경우

    이 원인은 일반적이지 않은 브랜치에서 커스텀 변환을 하지 않는 한 이런 상황을 꽤 자주 볼 수 있습니다.

  2. 디코딩 프로세스 중, 변환 중에 두 번 이상 Pool에 비트맵을 반환한 경우

    이 경우 문제의 원인을 파악하기 쉽습니다. 비트맵이 Pool에서 제거되지 않고 Pool에 여러 번 추가되면 다른 이미지가 동시에 표시되어, 두 개의 이미지 중 하나는 올바르게 표시되고 다른 하나는 잘못 표시 될 수 있습니다. 게다가 다른 뷰에서 참조하는 동안 동시에 recycle 될 수도 있습니다.

  3. onLoadCleared가 호출된 후에도 계속 리소스를 참조하거나, 또는 해당 Target이 지워진 후 Target에 로드된 리소스를 참조한 경우

    커스텀 target을 사용하는 경우 발생할 수 있습니다.

안타깝게도 비트맵을 추적하기 위해 수동 참조 계산을 수행해야하므로 이러한 종류의 버그를 추적하는 것이 매우 어려울 수 있습니다.
BitmapPool의 크기를 크게 줄이거나 BitmapPoolAdapter를 사용하여 충돌이 더 자주 발생하는지 확인하십시오. 메모리 캐시의 크기를 줄일 수도 있습니다. 두 경우 모두 파이프 라인의 길이를 줄입니다. 이는 Bitmap이 Recycled state에 더 빨리 도달하여 오류가 더 자주 발생할 수 있음을 의미합니다. 또한 비트맵 렌더링 오류, 기록 된 GL 경고 또는 다른 이미지 대신 잘못된 이미지가 나타나는지 주시하십시오. 이 모든 것은 버그를 재현한 신호입니다.

결론

따라서 Glide는 변환된 Bitmap을 내부적으로 recycle하기 때문에 imageView.setRecycler()하지 않아도 된다.

[Android] 웹뷰에서 동작하는 페이스북 로그인이 deprecated됨

1. 공지 전문

(1) 관련 문의 및 공식답변 링크

안녕하세요 철구 님, 자세한 내용에 감사드립니다.
로그 파일에서 ‘PLATFORM__LOGIN_DISABLED_FROM_WEBVIEW_OLD_SDK_VERSION’ 오류 코드를 확인할 수 있습니다. Android 웹뷰를 통한 Facebook 로그인(https://developers.facebook.com/blog/post/2021/06/28/deprecating-support-fb-login-authentication-android-embedded-browsers/)이 중단되었기 때문에 발생한 것으로 보입니다.
대신 이 링크를 통해 사용자 지정 탭을 적용하는 자세한 지침을 확인할 수 있습니다.
만약 문제가 지속된다면 사용 중인 SDK 버전과 영어로 표시된 오류 메시지 스크린숏과 함께 오류를 재현할 수 있도록 샘플 프로젝트를 제공 부탁드립니다.
감사합니다.

2. 공식 해결 가이드

(1) 페이스북 SDK 버전이 8.2 이상인지 확인

1
implementation 'com.facebook.android:facebook-android=sdk:8.2.0'

(2) 수정사항

앱 내부 웹뷰가 아닌 외부 브라우저를 통해 페이스북 로그인 진행하도록 변경

2021년 10월 5일부터 Facebook 로그인은 사용자 로그인에 Android 내장 브라우저(WebView) 사용을 더 이상 지원하지 않습니다. 사용자 경험이 중단되지 않도록 하려면 다음 체크리스트를 사용하여 대신 사용자 지정 탭을 사용하십시오.

3. 결론

웹뷰를 통해 페이스북 로그인 페이지에 접근하면 안 되며, 외부 브라우저를 띄워 페이스북 로그인 페이지에 접근하도록 수정해야 한다.

[Android] JCenter 지원종료

현재 상황(2021년 후반)

[Gradle] JCenter shutdown impact on Gradle builds에 따르면 JFrog에서 아래와 같이 공지했다고 한다.

  • JCenter는 read-only로 계속 제공될 것이나
  • 더이상 새로운 버전의 패키지는 받을 수 없다.
  • 모든 Bintray 서비스(JCenter에 배포하기 위한 플랫폼)는 중지되었다.

따라서 JCenter에서 기존에 있던 외부 라이브러리에 대한 정보는 계속 제공되기 때문에 현재 상황에서 바로 대응할 부분은 없을 것이다.

다만, 안드로이드 앱의 경우 build.gradle에 의존성을 추가한 외부 라이브러리의 버전 업데이트를 할 때 그 상위 버전이 JCenter에 업데이트 되어있지 않을테니 그때 해당 라이브러리 버전에 맞는 classpath를 추가하면 될 것으로 보인다.


JCenter 지원중단 시 상황(2021년 초중반)

JFrog에서 운영하는 JCenter, GoCenter 및 ChartCenter가 운영을 중지할 예정이다.

2021년 2월 28일 : GoCenter, ChartCenter에 라이브러리 등록 서비스 중지

2021년 3월 31일 : JCenter에 라이브러리 등록 서비스 중지

2021년 5월 1일 : GoCenter, ChartCenter에서 라이브러리 다운로드 서비스 중지

2022년 2월 1일 : JCenter에서 라이브러리 다운로드 서비스 중지

이유는 위의 요약링크에서 토론에서 말하기를

ExoPlayer의 issue에서 언급되기를, JCenter에서 악성코드가 포함된 라이브러리 패키지가 등록된 사고가 있었다고 하며, 이러한 사고방지 대책을 세우지 못하고 서비스를 닫는 것으로 보인다.

안드로이드 라이브러리는 JCenter에 의존한 게 많은데 따라서 대책을 세워야 한다. JCenter는 아래와 같이 레포지토리에 등록되어있다.

1
2
3
4
5
6
repositories {
google()
mavenCentral()
jcenter()
maven { url 'https://maven.fabric.io/public' }
}

또한 이 JCenter 지원 종료에 대한 안드로이드 공식 입장은 다음과 같다.

2022년 2월 1일까지 JCenter에서 기존 아티팩트를 다운로드할 수 있습니다. - 공식 문서

이에 관하여 추후에 또다른 공지가 올라올 예정이다.