Notice
Recent Posts
Recent Comments
Link
투케이2K
441. (kotlin/코틀린) [유틸 파일] getAppExitReason : getHistoricalProcessExitReasons 사용해 앱 종료 원인 확인 본문
Kotlin
441. (kotlin/코틀린) [유틸 파일] getAppExitReason : getHistoricalProcessExitReasons 사용해 앱 종료 원인 확인
투케이2K 2023. 11. 27. 19:18[개발 환경 설정]
개발 툴 : AndroidStudio
개발 언어 : Kotlin
[소스 코드]
// -----------------------------------------------------------------------------------------
// TODO [SEARCH FAST] : [RETURN] getAppExitReason : 이전 앱 종료 된 원인 확인 수행
// -----------------------------------------------------------------------------------------
fun getAppExitReason(mContext: Context, packageName: String): String {
/**
* // -----------------------------------------
* [getAppExitReason 메소드 설명]
* // -----------------------------------------
* 1. 이전 앱 수행 후 종료 된 원인 확인
* // -----------------------------------------
* 2. 호출 방식 :
*
* C_App.getAppExitReason(A_Intro@this, "com.example.javaproject")
*
* // -----------------------------------------
* 3. 리턴 데이터 : 앱 종료 된 원인 로그 리턴
*
* ProcessName : com.example.javaproject
* ProcessId : 19470
* ExitDate : 2023-11-27 09:47:25:827
* ExitReason : 사용자 요청으로 인해 애플리케이션 프로세스가 종료되었습니다
* ExitDescription : stop com.example.javaproject due to from pid 20148
* // -----------------------------------------
* 4. TODO 추가 설명 :
*
* ActivityManager : 앱 활동, 서비스 및 프로세스에 대한 정보를 제공합니다
* ActivityManager 는 디버깅 또는 정보 제공 목적으로 사용되며 앱의 런타임 동작에 영향을 주는 데 사용되어서는 안 됩니다
*
* // -----------------------------------------
* 5. 참 고 :
*
* https://developer.android.com/reference/android/app/ActivityManager
* https://developer.android.com/reference/android/app/ApplicationExitInfo
* // -----------------------------------------
*/
// [리턴 값 선언]
var returnData = ""
var M_LOG = ""
// [로직 처리 실시]
try {
// [인풋 패키지 명칭 널 체크 수행]
if (C_Util.stringNotNull(packageName) === true) {
// [ActivityManager 인스턴스 생성]
val manager = mContext.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
// [앱 종료 로그 획득 실시]
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
// [앱 종료 로그 획득 : getHistoricalProcessExitReasons] : [10 개 지정]
val exitList: List<ApplicationExitInfo> = manager.getHistoricalProcessExitReasons(packageName, 0, 10)
// [널 체크 수행]
if (exitList != null && exitList.size > 0) {
// [종료 시간 기준으로 정렬]
exitList.sortedByDescending { it-> it.timestamp }
// [for 문을 수행하면서 로그 확인]
var reason = ""
for (i in exitList.indices) {
reason = "\n\n" // [초기화]
// [ApplicationExitInfo 생성]
val exitInfo = exitList[i] as ApplicationExitInfo
reason += "ProcessName : ${exitInfo.processName}" + "\n"
reason += "ProcessId : ${exitInfo.pid}" + "\n"
reason += "ExitDate : ${SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS").format(Date(exitInfo.timestamp))}" + "\n"
if (exitInfo.reason == ApplicationExitInfo.REASON_ANR){
reason += "ExitReason : 응답이 없어(ANR) 애플리케이션 프로세스가 종료되었습니다" + "\n"
}
else if (exitInfo.reason == ApplicationExitInfo.REASON_CRASH){
reason += "ExitReason : 소스코드에서 처리되지 않은 예외로 인해 애플리케이션 프로세스가 중단되었습니다" + "\n"
}
else if (exitInfo.reason == ApplicationExitInfo.REASON_CRASH_NATIVE){
reason += "ExitReason : 네이티브 충돌로 인해 애플리케이션 프로세스가 중단되었습니다" + "\n"
}
else if (exitInfo.reason == ApplicationExitInfo.REASON_DEPENDENCY_DIED){
reason += "ExitReason : 종속성이 사라져 애플리케이션 프로세스가 종료되었습니다" + "\n"
}
else if (exitInfo.reason == ApplicationExitInfo.REASON_EXCESSIVE_RESOURCE_USAGE){
reason += "ExitReason : 과도한 리소스 사용으로 인해 시스템에서 응용 프로그램 프로세스가 종료되었습니다" + "\n"
}
else if (exitInfo.reason == ApplicationExitInfo.REASON_EXIT_SELF){
reason += "ExitReason : System.exit() 종료 코드 사용으로 프로세스가 종료되었습니다" + "\n"
}
else if (exitInfo.reason == ApplicationExitInfo.REASON_FREEZER){
reason += "ExitReason : 응용 프로그램 프로세스가 정지된 동안 동기화 바인더 트랜잭션을 수신했기 때문에 App Freezer 에 의해 종료되었습니다" + "\n"
}
else if (exitInfo.reason == ApplicationExitInfo.REASON_INITIALIZATION_FAILURE){
reason += "ExitReason : 초기화 실패로 인해 애플리케이션 프로세스가 종료되었습니다" + "\n"
}
else if (exitInfo.reason == ApplicationExitInfo.REASON_LOW_MEMORY){
reason += "ExitReason : 응용 프로그램 프로세스가 시스템 메모리 부족으로 인해 종료되었습니다" + "\n"
}
else if (exitInfo.reason == ApplicationExitInfo.REASON_OTHER){
reason += "ExitReason : 앱에서 조치를 취할 수 없는 다양한 다른 이유로 인해 시스템에서 애플리케이션 프로세스를 종료했습니다 (ex : 시스템 업데이트)" + "\n"
}
else if (exitInfo.reason == ApplicationExitInfo.REASON_PERMISSION_CHANGE){
reason += "ExitReason : 런타임 권한 변경으로 인해 애플리케이션 프로세스가 종료되었습니다" + "\n"
}
else if (exitInfo.reason == ApplicationExitInfo.REASON_SIGNALED){
reason += "ExitReason : OS 신호의 결과로 인해 애플리케이션 프로세스가 중단되었습니다" + "\n"
}
else if (exitInfo.reason == ApplicationExitInfo.REASON_UNKNOWN){
reason += "ExitReason : 알 수 없는 이유로 프로세스가 중단되었습니다" + "\n"
}
else if (exitInfo.reason == ApplicationExitInfo.REASON_USER_REQUESTED){
reason += "ExitReason : 사용자 요청으로 인해 애플리케이션 프로세스가 종료되었습니다" + "\n"
}
else if (exitInfo.reason == ApplicationExitInfo.REASON_USER_STOPPED){
reason += "ExitReason : 여러 사용자가 있는 장치에서 실행 중인 사용자가 중지되었기 때문에 응용 프로그램 프로세스가 종료되었습니다" + "\n"
}
else {
reason += "ExitReason : ${exitInfo.reason}" + "\n"
}
reason += "ExitDescription : ${exitInfo.description}" + "\n"
// ---------------------------------------
// [단일 로그 확인 및 리턴]
if (i == 0) {
M_LOG = "[Success] :: Get Exit Reason Check"
returnData = reason
break // [반복문 종료]
}
// ---------------------------------------
// [전체 출력 시 로그]
/*
S_Log._W_("Get Exit Log [" + i.toString() + "]", arrayOf(
reason.toString()
))
// */
// ---------------------------------------
}
} else {
M_LOG = "[Error] :: Get exitList Fail :: Reason :: Exit List Is Null"
}
} else {
M_LOG = "[Error] :: Get exitList Fail :: Reason :: Android Version 11 Low"
}
} else {
M_LOG = "[Error] :: Input Data Is Null"
}
} catch (e: Exception) {
M_LOG = "[Exception] :: " + e.message.toString()
S_Log._printStackTrace_(mContext, S_FinalMsg.LOG_BUG_STATE, null, e)
}
// [로그 출력 실시]
///*
// ===============================================================
S_Log._D_("이전 앱 수행 후 종료 된 원인 확인", arrayOf(
"INPUT :: $packageName",
"M_LOG :: $M_LOG",
"RETURN :: $returnData"
))
// ===============================================================
// */
// [리턴 반환 실시]
return returnData
}
반응형
'Kotlin' 카테고리의 다른 글
Comments