2024. 6. 28. 01:19ㆍ카테고리 없음
num = 0; // 반복수 초기화
tempList = new long[index];
humList = new long[index]; //온습도 평균데이터를 담을 배열 (정렬한 날짜만큼 배열생성)
dateList_s = new float[index];
for (int i = 0; i < index; i++) {
dateList.add(date.minusDays(i));
}//오늘부터 -i일 까지 날짜리스트를 생성
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); //날짜를 String에 담을 형식을 지정
AtomicInteger counter = new AtomicInteger(dateList.size()); // 남은 작업 수를 추적
Log.d("counter", String.valueOf(counter));
for (LocalDate getDate : dateList) { //데이트 리스트에서 LocalDate를 하나씩 추출하여 포맷팅 (ex 7일이면 7번 반복할것)
String extractDate = formatter.format(getDate); // 날짜데이터 추출을 위해 String에 임시로 담아서 사용 - 추출날짜
Log.d("extractDate", String.valueOf(getDate));
fireStore_MyDB.collection(extractDate).get().addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
@Override
public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
Log.d("extractDate22", String.valueOf(extractDate));
tempOfDay = new long[24];
humOfDay = new long[24]; //24시간 온습도를 받아서 평균을 낼 그릇배열
int k = 0;
for (QueryDocumentSnapshot doc : queryDocumentSnapshots) { // 24시간 온습도 데이터를 배열에 저장
tempOfDay[k] = doc.getLong("degree").longValue();
humOfDay[k] = doc.getLong("hum").longValue();
k++;
}
tempList[num] = (long) Arrays.stream(tempOfDay).average().getAsDouble();
humList[num] = (long) Arrays.stream(humOfDay).average().getAsDouble(); // 평균 온습도를 평균을 구해주는 OptionalDouble 함수
/*--------날짜형태의 float 데이터 만들기-----------*/
int month = getDate.getMonthValue();
int day = getDate.getDayOfMonth();
// float date_format = Float.parseFloat(month + "" + day);
float date_format = Float.parseFloat("" + day);
Log.d("date_format_Start", String.valueOf(date_format));
dateList_s[num] = date_format; // 날짜리스트 배열에 담은 날짜를 삽입
/*--------날짜형태의 float 데이터 만들기-----------*/
num++;
// 모든 데이터 로딩이 완료되었는지 확인
if (counter.decrementAndGet() == 0) {
drawRangeChart();
}
}
});
}
이것은 Firebase에서 스마트팜 프로젝트에 일,주,월 평균 온습도를 표시해주는 차트데이터를 담는 코드이다.
Firebase에서 차례대로 5월15일~ 5월9일 총 7일분량을 불러올거고. 평균온습도를 담아서 반환한다.
하지만 차트가 제대로 출력되지 않는 현상이 있어서 디버깅을 통해 확인해보니.
이런 재밌는 현상이 일어나고있었다. 이 디버깅을 요약해보자면.
for문이 한번 돌때마다 15일데이터-14일데이터-13일 데이터를 순차적으로 처리해야하지만.
DB관련 메소드가 실행되기도 전에 for문이 7번돌아버리고. DB는 비동기적으로 멋대로 출력되고있는 모습이시다.
이러니 데이터셋이 망가지고 제대로된 차트가 만들어지지 않고있었는데.
한번의 For문에서 한개의 데이터를 처리한 후, 다음 For문에서 다음날 데이터를 처리해야한다.
방법을 고안하던중. 재귀호출을 이용하면 현재날 데이터 처리가 끝나고나서 다음날 데이터를 처리할수있다고 결론지었다.
if (currentIndex >= dateList.size()) { // 평균 온습도 추출이 다 끝났다면, 라인차트를 그림
drawRangeChart();
return;
}
LocalDate date = dateList.get(currentIndex);
String extractDate = formatter.format(date);
Log.d("extractDate", extractDate);
fireStore_MyDB.collection(extractDate).get().addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
@Override
public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
Log.d("extractDate_DB", String.valueOf(extractDate));
tempOfDay = new long[24];
humOfDay = new long[24]; //24시간 온습도를 받아서 평균을 낼 그릇배열
int k = 0;
for (QueryDocumentSnapshot doc : queryDocumentSnapshots) { // 24시간 온습도 데이터를 배열에 저장
tempOfDay[k] = doc.getLong("degree").longValue();
humOfDay[k] = doc.getLong("hum").longValue();
k++;
}
long tempAvg = (long) Arrays.stream(tempOfDay).average().getAsDouble();
long humAvg = (long) Arrays.stream(humOfDay).average().getAsDouble(); // 평균 온습도를 평균을 구해주는 OptionalDouble 함수
synchronized (this) {
tempList[num] = tempAvg;
humList[num] = humAvg;
//날짜형태의 float 데이터 만들기
int day = date.getDayOfMonth();
float date_format = Float.parseFloat("" + day);
Log.d("format_date", String.valueOf(date_format));
dateList_s[num] = date_format; // 날짜리스트 배열에 포맷날짜 담기
num++;
}
//다음 날짜에 대해 재귀호출
loadDataRecursively(dateList, formatter, currentIndex + 1);
}
});
}
코드를 보면, Firebase의 데이터 처리가 끝났을때, 데이터 처리문 안에서 다음날짜에 대한 처리를 재귀호출 했다.
정보처리 산업기사에서 배웠던 재귀함수 내용을 이렇게 직접 사용해보는것은 처음이였다.
[문제2] NegativeArraySizeIndex 오류 반환
재귀호출을 이용해 데이터를 불러오니 순서대로 잘 받아와졌다. 그런데 문제가 하나 더 생겼다.
디버깅을 통해 모든 단위에서 데이터가 잘 넘겨지는것을 확인했으나, NegativeArraySizeIndex 오류를 반환하며 앱이 다운되버리는 것이였다.
검색을통해 의미를 알아보니, 배열의 크기가 음수로 지정되어 생기는 오류라고 하는데. 디버깅에선 배열 크기에 대해선 아무 문제가 없었다.
그러던중 옆자리 학우와 얘기를 나누다 LineChart 외부라이브러리에 대한 stackOverFlow 글을 하나 찾아볼 수 있었다.
https://stackoverflow.com/questions/67302005/mpchart-java-lang-negativearraysizeexception-54
MPChart java.lang.NegativeArraySizeException: -54
I tried to fix this for the past 3 days. I have no idea what to do anymore. The most common thing I found is to sort the data which didn't work out for me. var valuesTemperature: ArrayList<Entry...
stackoverflow.com
내용을 요약하자면 이렇다. "정렬을 해줘야함"
추측가는 문제는 있었다. 일일데이터 (1시~24시)는 문제가 없었는데.
주간,월간 데이터는 15일~9일(7일분량) 처럼 내림차순으로 받아오고 있었던것.
설마 이것이 문제일까 싶었지만 놀랍게도 맞았다.
레전드레전드... 4주간 고생했던 문제가 참 어이도없는 사유였단것이 ㅋㅋ
LineChart는 x축, 즉 기간을 나타내는 부분이 오름차순 정렬이 되어야한다.
좀더 알아 봐야하겠지만. 이런식으로 정렬이 강제된다면 차트의 활용성이 많이 떨어지기에 동작구조에 대해 좀 더 알아봐야할거같다.
당장엔 프로젝트의 마무리가 급하니 n일전 의 데이터로 활용하면 급한불은 꺼질 것 같다.