[유니티 C#] 안드로이드에 삽입된 유니티 프로세스 종료 방법
안드로이드에 유니티를 aar로 삽입하여 실행하다가 종료할 때 메모리 누수 해결 방법 (ServiceConnect
네이버 블로그 백업 글 입니다. https://blog.naver.com/keutana/223099297377 안드로이드에 유니티를 aar로 삽입하여 실행하다가 종료할 때 메모리 누수 해결 방법 (ServiceConnect http://lancekun.com/blog/?p=599 이 포
redasol.tistory.com
이전 글에서 이어집니다.
다음 포스트들을 참조했습니다.
https://velog.io/@mjini/Android-finish-vs-finishAffinity
[Android] finish() vs finishAffinity()
현재 Activity 종료, startActivityForResult()로 호출했다면 ActivityResult 전달현재 스택에 있는 모든 Activity 종료 앱 종료시 Root Activity에서 finish()를 사용해서 종료해야 하지만, 이 함수를 사용하면 어느
velog.io
https://discussions.unity.com/t/finish-on-unityplayeractivity-kills-the-entire-application/114616
finish on UnityPlayerActivity kills the entire application
I have an Android project in which I have one Unity activity integrated in it. I’m running into an issue when i call finish() from within unity activity to return the main activity. It causes the entire process to be killed (it sends signal 9 – SIGKILL
discussions.unity.com
https://forum.unity.com/threads/how-to-quit-unity-android-app-using-process-killprocess.432452/
How to quit Unity Android app using Process.KillProcess
I want to quit a Unity Android app in such a way that the process is killed completely, and not paused or suspended or anything similar. To meet this...
forum.unity.com
유니티에서 안드로이드 코드를 불러 유니티 프로세스를 종료하는 방법은 크게 4가지가 있다.
1. finish();
2. onBackPressed();
3. System.exit(0);
4. Android.OS.Process.KillProcess(Android.OS.Process.MyPid());
근데 문제는 System.exit(0); 를 제외하고 실행되고 있는 앱을 종료하고 있다.
안드로이드 앱에서 유니티를 실행하여 안드로이드 액티비티 위에 유니티 액티비티를 실행했기에 유니티만 종료하는 줄 알았는데 테스트해보니 3번을 제외하고 전부 안드로이드 앱을 종료하고 있다.
이전 글에서는 자기가 만든 앱 패키지 네임으로 인스턴스를 불러 안드로이드 코드의 함수를 실행했다면 이번에는 기본으로 제공되는 걸로 System.exit(0)을 실행했다.
과거에 작성된 프로젝트에서 블루투스 서비스를 확인할 때 사용한 코드와 참조 포스트 중 두 번째 포스트를 활용했다.
일단 유니티 프로그램이 안드로이드의 블루투스 서비스를 확인하는 코드는 다음과 같다.
유니티가 기본으로 제공하는 com.unity3d.player.UnityPlayer 로 참조하여 해당 서비스가 작동중인지 확인하고 있다.
그리고 참조한 포스트에서는
AndroidJavaClass jc = new AndroidJavaClass ("com.unity3d.player.UnityPlayer");
AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject> ("currentActivity");
jo.Call ("goBack");
이렇게 함수를 호출하고 있다.
그러면 유니티에서 안드로이드 코드에 작성한 quitunity 란 함수를 부르려고 한다.
먼저 QuitManager를 작성하자.
public class QuitManager : MonoBehaviour
{
private AndroidJavaObject currentActivity;
public static QuitManager self = null;
public static QuitManager instance
{
// 안드로이드가 현재 화면을 띄우고 있는 액티비티를 리턴함 ( 지금 현재 어디를 보고 있어요? )
get
{
if (self == null)
{
Debug.LogWarning("QuitManager instance set start");
self = new QuitManager();
AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
jc.GetStatic<AndroidJavaObject>("currentActivity");
self.currentActivity = jc.GetStatic<AndroidJavaObject>("currentActivity");
Debug.LogWarning("QuitManager instance set end");
}
return self;
}
}
}
그리고 유니티를 종료하기위해 안드로이드 코드를 호출하는 함수를 작성하자.
public void FinishApp()
{
try
{
if (currentActivity != null)
{
Debug.LogWarning("currentActivity Call finish");
currentActivity.Call("unityquit");
}
}
catch (System.Exception e)
{
Debug.LogWarning("currentActivity Call finish fail -> " + e.Message);
AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
currentActivity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
currentActivity.Call("unityquit");
}
}
그리고 유니티를 종료하는 버튼을 눌렀을 때 작동하는 코드를 QuitManager가 아닌 다른 스크립트에서 작성하자.
try
{
QuitManager.instance.FinishApp();
}
catch (System.Exception e)
{
Debug.LogWarning("finish fail -> "+ e.Message );
}
이제 유니티 프로젝트를 안드로이드 프로젝트로 Export하고 UnityPlayerActivity.java 파일에 다음 함수를 작성하자
public void unityquit() {
Log.w("UnityPlayerActivity", "unityquit begin ");
System.exit(0);
}
작동방식은 다음과 같다.
QuitManager.instance.FinishApp(); 를 호출하면 QuitManager에서 인스턴스를 만들면서 안드로이드 액티비티를 참조한다.
System.exit(0)로 유니티 액티비티만 종료되고 안드로이드 액티비티가 즉시 다시 실행된다.
이전 포스트에서 작성한 건 디버그 빌드에서만 작동이 되었다.
그 이유는 릴리즈 빌드를 할 때 빌드 파일의 크기를 줄이기위해 빌드 옵션을 넣는데
minifyEnabled true
zipAlignEnabled true // apk 최적화
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
릴리즈 빌드 옵션에 보통 이와 같이 옵션을 설정할 것이다.
이렇게 하고 빌드를 한다면 작성한 unityquit() 함수를 찾을 수 없다는 에러 메세지가 나올 것이다.
안드로이드 스튜디오가 볼 때 사용되지 않는 unityquit를 빌드파일에서 제외하기 때문인데 해당 함수를 제외를 안 하도록 설정해야한다.
먼저 유니티에서 설정한 Pacage Name이 필요하다. UnityPlayerActivity 스크립트 상단에도 적혀있는 package 이름을
proguard 파일에 다음 구문을 추가한다.
-keep class com.example.unityapp.* { *; }
유니티와 안드로이드 코드에서 보이는 패키지 이름을 쓰면 된다.
이 구문을 추가하면 해당 패키지를 가진 클래스의 모든 스크립트가 빌드파일에 포함되므로 위에서 작성했던 unityquit 함수를 찾을 수 있다.