지난번 ios에 이어, 이번에는 android에 app icon과 splash screen 적용하기를 기록해볼 예정이다. xcode만으로 모든 설정을 끝냈던 ios와는 달리 android는 직접 파일과 폴더를 수정해야 했던 만큼 개인적인 난이도는 더욱 높았다.
먼저 app icon과 splash 이미지를 준비해야한다. ios와 동일하게 1024x1024 사이즈 아이콘 이미지 하나만 준비하고 generator 웹 사이트를 이용할 예정이다. 가장 유명한 사이트는 이곳 인것 같지만 생성되는 파일이 내 RN 프로젝트와는 좀 맞지 않는 것 같아서 추가적으로 서치하다가 찾아낸 사이트가 바로 아래 추천 사이트다. 다 해결하기 나름이겠지만 조금이라도 덜 고민하고 싶다면 아래 사이트를 사용하는 것을 추천한다.
사이즈별 아이콘을 생성했으면 프로젝트 내 icon 파일을 교체해야한다. 경로는 '[프로젝트명]/android/app/src/main/res'이다.
이곳에 mipmap으로 시작하는 폴더들이 여러개 있을건데, 아까 웹사이트에서 생성한 폴더들로 그대로 대치하면 된다. (기본적으로 폴더 이름과 이미지 파일의 이름은 기존의 이름과 똑같겠지만, 혹시 모르니 이름이 바뀌지 않았나 한번쯤 확인해보는 것도 좋다.) 이것으로 아이콘 이미지 설정은 끝이다.
스플래시 이미지를 설정하기 전에, 우선 미리 생성해둔 splash_screen 이미지 파일을 'app/src/main/res/drawable' 폴더에 넣어주었다. 이제 해당 이미지 파일에 접근해서 스플래시 스크린으로 띄워주기만 하면 된다. 그 작업을 위해서 react-native-splash-screen이라는 외부 라이브러리를 사용했다.
라이브러리 문서: https://github.com/crazycodeboy/react-native-splash-screen
라이브러리 설치 후 'app/src/main/res' 경로에 layout 폴더를 만들고 그 안에 launch_screen.xml 파일을 만들어 아래 코드를 입력한다. 여기서 주의할 점은 android:src="@drawable/launch_screen"에 쓰인 launch_screen과 실제 drawable 폴더에 넣었던 이미지 파일의 이름이 같아야 한다는 것이다. (이미지 이름을 splash_image라고 막 지어놓고 까먹은 바람에 빌드 중에 소스를 못찾겠다는 에러를 여러번 만났었다..ㅠ)
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/launch_screen"
android:scaleType="centerCrop" />
</RelativeLayout>
그리고 나서 'app/src/main/res/drawable' 경로에 splashscreen.xml 파일을 만들어 아래 내용을 추가한다. 이번에도 아까와 동일하게 파일명을 잘 확인해야한다.
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<bitmap
android:gravity="center"
android:src="@drawable/launch_screen" />
</item>
</layer-list>
이제 'app/src/main/java/com/[프로젝트명]' 경로에 위치한 MainActivity.java 파일에서 스플래시 스크린을 보여주도록 설정하기만 하면 된다.
import android.os.Bundle; // here
import com.facebook.react.ReactActivity;
// react-native-splash-screen >= 0.3.1
import org.devio.rn.splashscreen.SplashScreen; // here
// react-native-splash-screen < 0.3.1
import com.cboy.rn.splashscreen.SplashScreen; // here
public class MainActivity extends ReactActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
SplashScreen.show(this); // here
super.onCreate(savedInstanceState);
}
// ...other code
}
//코드 출처: https://github.com/crazycodeboy/react-native-splash-screen
//현재 진행중인 프로젝트는 MainActivity.java 파일의 구조가 조금 바뀌었는지,
//onCreate함수가 없기 때문에 SplashScreen.show(this)를 넣어줄 수 없었다.
//그래서 그냥 onCreate함수까지 통째로 복붙하자 정상 작동했다.
이렇게 하고 앱을 다시 빌드하면 스플래시 스크린은 정상적으로 보이겠지만, 시간이 지나도 사라지지 않는 문제가 발생한다. 이제 이부분은 아래와 같이 RN의 Root component에서 스플래시 스크린이 사라지도록 처리해주면 된다.
import SplashScreen from 'react-native-splash-screen';
const App = () => {
...
useEffect(() => {
//setTimeout을 이용하면 몇초간 스플래시 스크린을 보여주고 싶은지 설정할 수 있다.
setTimeout(() => {
SplashScreen.hide();
}, 1000);
}, []);
...
}
export default App
이렇게 해서 android에서도 아이콘과 스플래시 스크린을 적용하는 과정이 모두 끝이 났다. 확실히 ios와 비교해 android는 사전에 셋팅해야하는 부분도 많고, 조금만 틀려도 오류가 발생하기 때문에 쉽지 않은 작업이었다. (native 공부를 하긴 해야할거같다)
게다가 이번에 사용한 react-native-splash-screen 라이브러리의 경우 마지막 업데이트로부터 시간도 많이 지났기 때문에, 아직은 사용하는데 크게 문제는 없지만 앞으로 조금 걱정되는 것도 사실이다. 게다가 이전에 ios에 해당 라이브러리를 적용했을 때는 SplashScreen.hide()가 동작하지 않아 스플래시 스크린이 사라지지 않는 버그(가 아니라 내가 놓치고 있었던게 있었을지도 모른다.)도 있었기에 장기적으로는 해당 라이브러리가 아니라 다른 방법으로 구현하는 방법도 찾아볼 필요가 있을 것 같다.