다음은 Http 요청과 응답을 받는 부분만 분리해서 별도의 클래스로 뺏습니다. 이 클래스역시 약간만 손보시면 다른데서도 재사용이 쉽게 가능합니다.
public class HttpClient {
public String sendRequest(String endpoint, String postParameters) throws Exception {
StringBuilder jsonHtml = new StringBuilder();
URL url = new URL(endpoint);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
if (conn != null) {
conn.setConnectTimeout(10000);
conn.setReadTimeout(5000);
conn.setRequestMethod("POST");
conn.connect();
OutputStream outputStream = conn.getOutputStream();
outputStream.write(postParameters.getBytes(StandardCharsets.UTF_8));
outputStream.flush();
outputStream.close();
if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
while (true) {
String line = br.readLine();
if (line == null) {
break;
}
jsonHtml.append(line).append("\n");
}
br.close();
}
conn.disconnect();
}
return jsonHtml.toString();
}
}
핵심적인 코드는 이미 사용하신 코드를 그대로 복사했습니다. sendRequest메소드는 예외처리를 직접하지 않고 예외를 밖으로 던집니다. 이 클래스를 사용하는 곳에서 예외처리를 최종적으로 할 겁니다.
다음은 AsyncTask 클래스입니다.
public class GetIlluminanceChartDataTask extends AsyncTask<String, Integer, IlluminateChartResponse> {
// 외부와는 리스너를 사용하여 통신함.
interface Listener {
void onResponse(IlluminateChartResponse response);
}
private static final String TAG_JSON = "tngusdl98";
private final String endpoint;
private final String postParameters;
private Listener listener;
public GetIlluminanceChartDataTask(String endpoint, String postParameters) {
this.endpoint = endpoint;
this.postParameters = postParameters;
}
public void setListener(Listener listener) {
this.listener = listener;
}
@Override
IlluminateChartResponse doInBackground(String... params) {
HttpClient httpClient = new HttpClient();
try {
String jsonString = httpClient.sendRequest(endpoint, postParameters);
IlluminanceChartData chartData = parseJson(jsonString);
return new IlluminateChartResponse(chartData);
} catch (Exception e) {
e.printStackTrace();
return new IlluminateChartResponse(e);
}
}
private IlluminanceChartData parseJson(String str) throws JSONException {
List<Entry> standardEntries = new ArrayList<>();
List<Entry> illuminanceEntries = new ArrayList<>();
JSONObject jsonObject = new JSONObject(str);
JSONArray jsonArray = jsonObject.getJSONArray(TAG_JSON);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject item = jsonArray.getJSONObject(i);
String illuminance = item.getString("avg");
illuminanceEntries.add(new Entry(i, Float.valueOf(illuminance)));
for (int j = 16000; j <= 27000; j++) { // 최소, 최댓값 설정.
standardEntries.add(new Entry(i, j));
}
}
return new IlluminanceChartData(standardEntries, illuminanceEntries);
}
@Override
void onPostExecute(IlluminateChartResponse response) {
if (listener != null) {
listener.onResponse(response);
}
}
}
잘 보시면 Listener 인터페이스가 추가되었습니다. 이 클래스는 View.OnClickListener와 같은 용도로 생각하시면 됩니다. 내가 원하는 작업이 완료되면 이 리스너를 통해 통보를 받기위한 게 주된 목적입니다. onPostExecute에서 모든 처리가 끝나고 결과를 리스너를 통해 알려주게 됩니다. 따라서 이 AsyncTask를 호출하는 곳에서는 Listener 인터페이스를 구현하여 넘겨주면 작업이 끝나고 onResponse를 통해 결과를 받게 됩니다. onResponse를 구현하는 쪽에서는 응답결과를 받고나서 뭘할지 작성하면 됩니다. 님의 경우는 차트를 만드는 코드가 위치하겠죠.
다음은 챠트를 만드는 클래입니다. 이 클래스는 제가 MPChart를 사용하지 않는 관계로 에러가 있을 수 있습니다. 뼈대가 되는 구조만 가져다 사용하시면 됩니다. 이 클래스에는 기존에 onPostExecute안의 챠트 만드는 코드를 모두 옮기시면 됩니다.
// 조도 그래프 구현.
public class IlluminanceChartBuilder {
private final IlluminanceChartData chartData;
private final Graph illuGraph;
public ChartRenderer(Graph illuGraph, IlluminanceChartData chartData) {
this.illuGraph = illuGraph;
this.chartData = chartData;
}
private void buildXAxis() {
XAxis xAxis = illuGraph.getXAxis();
xAxis.setDrawGridLines(true);
xAxis.setDrawLabels(false);
xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
xAxis.setAxisLineWidth(1.5f);
}
private void buildYAxis() {
buildYAxisLeft();
buildYAxisRight();
}
// Y축 오른쪽면 라벨과 선만 그려지게.
private void buildYAxisLeft() {
YAxis yAxisLeft = illuGraph.getAxisLeft();
yAxisLeft.setDrawGridLines(true);
yAxisLeft.setAxisMinimum(0f);
yAxisLeft.setAxisMaximum(70000f);
yAxisLeft.setAxisLineWidth(1.5f);
}
// Y축 왼쪽면 비활성
private void buildYAxisRight() {
YAxis yAxisRight = illuGraph.getAxisRight();
yAxisRight.setDrawLabels(false);
yAxisRight.setDrawAxisLine(false);
yAxisRight.setDrawGridLines(false);
}
// 선은 초록색, 선만 그려지게.
private LineDataSet buildStandardDataSet() {
LineDataSet dataSet = new LineDataSet(chartData.getStandards(), "");
dataSet.setColor(Color.parseColor("#1AB2EBF4"));
dataSet.setLineWidth(3f);
dataSet.setDrawCircles(false);
dataSet.setDrawCircleHole(false);
dataSet.setDrawValues(false);
return dataSet;
}
private LineDataSet buildIlluminanceDataSet() {
LineDataSet dataSet = new LineDataSet(chartData.getIlluminances(), "조도 그래프"); // 선은 노란색, 원&선만 그려지게.
dataSet.setColor(Color.parseColor("#FFBB00"));
dataSet.setLineWidth(1.5f);
dataSet.setDrawCircles(false);
dataSet.setDrawCircleHole(false);
dataSet.setDrawValues(false);
return dataSet;
}
// Legend 비활성화.
private void buildLegend() {
Legend legend = illuGraph.getLegend();
legend.setEnabled(false);
}
private void buildCharTitle() {
SimpleDateFormat todayF = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()); // 오늘 날짜 구하기.
Calendar toCalendar = Calendar.getInstance();
String today = todayF.format(toCalendar.getTime());
SimpleDateFormat weekF = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()); // 일주일 전 날짜 구하기.
Calendar weCalendar = Calendar.getInstance();
weCalendar.add(Calendar.DATE, -6);
String week = weekF.format(weCalendar.getTime());
illuGraph.getDescription().setText("조도 데이터 (" + week + " ~ " + today + ")");
illuGraph.getDescription().setTextSize(8f);
illuGraph.getDescription().setTextAlign(Paint.Align.RIGHT);
int width = illuGraph.getWidth();
int height = illuGraph.getHeight();
illuGraph.getDescription().setPosition(width - 50, height - 8);
}
public void build() {
buildCharTitle();
buildLegend();
buildXAxis();
buildYAxis();
illuData.addDataSet(buildStandardDataSet());
illuData.addDataSet(buildIlluminanceDataSet());
illuGraph.setTouchEnabled(false);
illuGraph.setData(illuData);
illuGraph.invalidate();
}
}