Notice
Recent Posts
Recent Comments
Link
투케이2K
698. (Android/Java) [유틸 파일] getAppExitReason : getHistoricalProcessExitReasons 사용해 앱 종료 원인 확인 본문
Android
698. (Android/Java) [유틸 파일] getAppExitReason : getHistoricalProcessExitReasons 사용해 앱 종료 원인 확인
투케이2K 2023. 11. 27. 19:15[개발 환경 설정]
개발 툴 : AndroidStudio
[소스 코드]
// -----------------------------------------------------------------------------------------
// TODO [SEARCH FAST] : [RETURN] getAppExitReason : 이전 앱 종료 된 원인 확인 수행
// -----------------------------------------------------------------------------------------
public static String getAppExitReason(Context mContext, String packageName) {
/**
* // -----------------------------------------
* [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
* // -----------------------------------------
* */
// [리턴 값 선언]
String returnData = "";
String M_LOG = "";
// [로직 처리 실시]
try {
// [인풋 패키지 명칭 널 체크 수행]
if (C_Util.stringNotNull(packageName) == true){
// [ActivityManager 인스턴스 생성]
ActivityManager manager = (ActivityManager) mContext.getSystemService(ACTIVITY_SERVICE);
// [앱 종료 로그 획득 실시]
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
// [앱 종료 로그 획득 : getHistoricalProcessExitReasons] : [10 개 지정]
List exitList = manager.getHistoricalProcessExitReasons(packageName,0, 10);
// [널 체크 수행]
if (exitList != null && exitList.size()>0){
// [종료 시간 기준으로 정렬]
exitList.sort(Comparator.comparing(ApplicationExitInfo::getTimestamp).reversed());
// [for 문을 수행하면서 로그 확인]
String reason = "";
for (int i=0; i<exitList.size(); i++){
reason = "\n\n"; // [초기화]
// [ApplicationExitInfo 생성]
ApplicationExitInfo exitInfo = (ApplicationExitInfo) exitList.get(i);
reason += "ProcessName : " + String.valueOf(exitInfo.getProcessName()) + "\n";
reason += "ProcessId : " + String.valueOf(exitInfo.getPid()) + "\n";
reason += "ExitDate : " + String.valueOf(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS").format(new Date(exitInfo.getTimestamp()))) + "\n";
if (exitInfo.getReason() == ApplicationExitInfo.REASON_ANR){
reason += "ExitReason : " + "응답이 없어(ANR) 애플리케이션 프로세스가 종료되었습니다" + "\n";
}
else if (exitInfo.getReason() == ApplicationExitInfo.REASON_CRASH){
reason += "ExitReason : " + "소스코드에서 처리되지 않은 예외로 인해 애플리케이션 프로세스가 중단되었습니다" + "\n";
}
else if (exitInfo.getReason() == ApplicationExitInfo.REASON_CRASH_NATIVE){
reason += "ExitReason : " + "네이티브 충돌로 인해 애플리케이션 프로세스가 중단되었습니다" + "\n";
}
else if (exitInfo.getReason() == ApplicationExitInfo.REASON_DEPENDENCY_DIED){
reason += "ExitReason : " + "종속성이 사라져 애플리케이션 프로세스가 종료되었습니다" + "\n";
}
else if (exitInfo.getReason() == ApplicationExitInfo.REASON_EXCESSIVE_RESOURCE_USAGE){
reason += "ExitReason : " + "과도한 리소스 사용으로 인해 시스템에서 응용 프로그램 프로세스가 종료되었습니다" + "\n";
}
else if (exitInfo.getReason() == ApplicationExitInfo.REASON_EXIT_SELF){
reason += "ExitReason : " + "System.exit() 종료 코드 사용으로 프로세스가 종료되었습니다" + "\n";
}
else if (exitInfo.getReason() == ApplicationExitInfo.REASON_FREEZER){
reason += "ExitReason : " + "응용 프로그램 프로세스가 정지된 동안 동기화 바인더 트랜잭션을 수신했기 때문에 App Freezer 에 의해 종료되었습니다" + "\n";
}
else if (exitInfo.getReason() == ApplicationExitInfo.REASON_INITIALIZATION_FAILURE){
reason += "ExitReason : " + "초기화 실패로 인해 애플리케이션 프로세스가 종료되었습니다" + "\n";
}
else if (exitInfo.getReason() == ApplicationExitInfo.REASON_LOW_MEMORY){
reason += "ExitReason : " + "응용 프로그램 프로세스가 시스템 메모리 부족으로 인해 종료되었습니다" + "\n";
}
else if (exitInfo.getReason() == ApplicationExitInfo.REASON_OTHER){
reason += "ExitReason : " + "앱에서 조치를 취할 수 없는 다양한 다른 이유로 인해 시스템에서 애플리케이션 프로세스를 종료했습니다 (ex : 시스템 업데이트)" + "\n";
}
else if (exitInfo.getReason() == ApplicationExitInfo.REASON_PERMISSION_CHANGE){
reason += "ExitReason : " + "런타임 권한 변경으로 인해 애플리케이션 프로세스가 종료되었습니다" + "\n";
}
else if (exitInfo.getReason() == ApplicationExitInfo.REASON_SIGNALED){
reason += "ExitReason : " + "OS 신호의 결과로 인해 애플리케이션 프로세스가 중단되었습니다" + "\n";
}
else if (exitInfo.getReason() == ApplicationExitInfo.REASON_UNKNOWN){
reason += "ExitReason : " + "알 수 없는 이유로 프로세스가 중단되었습니다" + "\n";
}
else if (exitInfo.getReason() == ApplicationExitInfo.REASON_USER_REQUESTED){
reason += "ExitReason : " + "사용자 요청으로 인해 애플리케이션 프로세스가 종료되었습니다" + "\n";
}
else if (exitInfo.getReason() == ApplicationExitInfo.REASON_USER_STOPPED){
reason += "ExitReason : " + "여러 사용자가 있는 장치에서 실행 중인 사용자가 중지되었기 때문에 응용 프로그램 프로세스가 종료되었습니다" + "\n";
}
else {
reason += "ExitReason : " + String.valueOf(exitInfo.getReason()) + "\n";
}
reason += "ExitDescription : " + String.valueOf(exitInfo.getDescription()) + "\n\n";
// ---------------------------------------
// [단일 로그 확인 및 리턴]
if (i == 0){
M_LOG = "[Success] :: Get Exit Reason Check";
returnData = reason;
break; // [반복문 종료]
}
// ---------------------------------------
// [전체 출력 시 로그]
/*
S_Log._W_("Get Exit Log [" + String.valueOf(i) + "]", new String[]{
String.valueOf(reason)
});
// */
// ---------------------------------------
}
}
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 (Exception e) {
M_LOG = "[Exception] :: " + String.valueOf(e.getMessage());
S_Log._printStackTrace_(mContext, S_FinalMsg.LOG_BUG_STATE, null, e);
}
// [로그 출력 실시]
///*
// ===============================================================
S_Log._D_("이전 앱 수행 후 종료 된 원인 확인", new String[]{
"INPUT :: " + String.valueOf(packageName),
"M_LOG :: " + String.valueOf(M_LOG),
"RETURN :: " + String.valueOf(returnData)
});
// ===============================================================
// */
// [리턴 반환 실시]
return returnData;
}
[결과 출력]
D///===========//: ================================================
I/: [LOG :: CLASS PLACE :: com.example.javaproject.C_App.getAppExitReason(C_App.java:9310)]
I/: ----------------------------------------------------
I/: [LOG :: NOW TIME :: 2023-11-27 09:47:40 월요일]
I/: ----------------------------------------------------
I/: [LOG :: DESCRIPTION :: 이전 앱 수행 후 종료 된 원인 확인]
I/: ----------------------------------------------------
I/: [LOG :: INPUT :: com.example.javaproject]
I/: ----------------------------------------------------
I/: [LOG :: M_LOG :: [Success] :: Get Exit Reason Check]
I/: ----------------------------------------------------
I/: [LOG :: RETURN ::
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
]
D///===========//: ================================================
반응형
'Android' 카테고리의 다른 글
Comments