본문 바로가기

Android

디버그 모드에서만 동작하는 코드 & 크래쉬 로그를 저장하는 방법

안드로이드 ADT 17 이후 부터는 BuildConfig.DEBUG 플래그를 이용해서 

마켓 릴리즈 용 Signing이 되었는지 여부를 확인할 수 있게 되었습니다.


그래서 아래와 같이 코딩을 하면, 개발 할 때는 로그 메시지가 나오지만, 릴리즈 모드에서는 나오지 않게 됩니다.



if (BuildConfig.DEBUG) { // above ADT 17
		Log.d("TAG", "DEBUG Message");
}



디버그 시에만 써야하는 코드는 어떤 것이 있을까요?

대표적으로는 크래쉬 핸들러가 있는데요, 크래쉬 발생 시 개발자가 제어할 수 있게 해 주는 클래스입니다.

이를 파일로 저장하는 기능을 한 번 넣어 보겠습니다.

(물론 구글플레이에 올리면 구글플레이에서 크래쉬 로그를 수집해 주지만, 개발 단계에서 크래쉬 로그를 수집하고 싶을 수 있으니까요)

참고: http://stackoverflow.com/questions/601503/how-do-i-obtain-crash-data-from-my-android-application


if (BuildConfig.DEBUG) { // above ADT 17

			if (!(Thread.getDefaultUncaughtExceptionHandler() instanceof CustomExceptionHandler)) {
				Thread.setDefaultUncaughtExceptionHandler( //
				new CustomExceptionHandler(//
						Environment.getExternalStorageDirectory() + "/" + getString(R.string.app_name)//
						, null));
			}
		}


여기에서 이용할 핸들러는 아래와 같이 만들면 됩니다. 파일로 저장하기 / 서버로 보내기가 가능합니다.


public class CustomExceptionHandler implements UncaughtExceptionHandler {
	private UncaughtExceptionHandler defaultUEH;
	private String localPath;
	private String url;

	/*
	 * if any of the parameters is null, the respective functionality will not be used
	 */
	public CustomExceptionHandler(String localPath, String url) {
		this.localPath = localPath;
		this.url = url;
		this.defaultUEH = Thread.getDefaultUncaughtExceptionHandler();
	}

	public void uncaughtException(Thread t, Throwable e) {
		SimpleDateFormat s = new SimpleDateFormat("yyyy_MM_dd_HHmmss");
		s.setTimeZone(TimeZone.getDefault());
		String timestamp = s.format(new Date());
		final Writer result = new StringWriter();
		final PrintWriter printWriter = new PrintWriter(result);
		e.printStackTrace(printWriter);
		
		String stacktrace = result.toString();
		printWriter.close();
		String filename = timestamp + "_stacktrace" + ".txt";

		if (localPath != null) {
			writeToFile(stacktrace, filename);
		}
		if (url != null) {
			sendToServer(stacktrace, filename);
		}

		defaultUEH.uncaughtException(t, e);
	}

	private void writeToFile(String stacktrace, String filename) {
		try {
			BufferedWriter bos = new BufferedWriter(new FileWriter(localPath + "/" + filename));
			bos.write(stacktrace);
			bos.flush();
			bos.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private void sendToServer(String stacktrace, String filename) {
		DefaultHttpClient httpClient = new DefaultHttpClient();
		HttpPost httpPost = new HttpPost(url);
		List nvps = new ArrayList();
		nvps.add(new BasicNameValuePair("filename", filename));
		nvps.add(new BasicNameValuePair("stacktrace", stacktrace));
		try {
			httpPost.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
			httpClient.execute(httpPost);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}