파일을 다운로드 할때 파일의 존재 유무를 확인 한 뒤 다운로드를 실행해야 하는 경우가 있다. 이럴때 URL이 가르키는 경로에 파일이 존재하는지 유무를 확인해 보는 방법에 대해서 알아보자.
구글느님께 물어보면 이러한 답변을 많이 받을 수 있다. 하지만, con.getResponseCode() 이 부분에서 아래와 같은 네트워크 오류가 발생한다ㅠㅠ
android.os.NetworkOnMainThreadException
private boolean exists(String URLName) {
try {
HttpURLConnection.setFollowRedirects(false);
HttpURLConnection con = (HttpURLConnection) new URL(URLName).openConnection();
con.setRequestMethod("HEAD");
if (con.getResponseCode() == HttpURLConnection.HTTP_OK) {
return true;
} else {
return false;
}
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
android.os.NetworkOnMainThreadException 오류는 Android OS 아이크스크림샌드위치(정확히 기억이...ㅠ) 부터 방생하는 에러로 네트워크 처리를 해 줄때는 비동기 처리를 반드시 해 주어야 한다는 것이다.
그렇다면 비동기 처리 중 가장 많이 쓰이는 AsyncTask로 구현을 해보면 아래와 같다.
public class MyDownloadTask extends AsyncTask<String, Void, Boolean>
{
private int responseHttp = 0;
private boolean flag = false;
private Context mContext;
private final ProgressDialog dlg;
public MyDownloadTask(Context mContext) {
this.mContext = mContext;
ProgressDialog mDialog = new ProgressDialog(mContext);
dlg = (ProgressDialog) mDialog;
dlg.setMessage(mContext.getText(R.string.wait_msg));
dlg.setIndeterminate(true);
dlg.setCancelable(false);
}
@Override
protected void onPreExecute() {
dlg.show();
}
@Override
protected Boolean doInBackground(String... urlPath) {
try {
URL url = new URL(urlPath[0]);
URLConnection connection = url.openConnection();
connection.setConnectTimeout(2000);
HttpURLConnection httpConnection = (HttpURLConnection) connection;
responseHttp = httpConnection.getResponseCode();
if (responseHttp == HttpURLConnection.HTTP_OK) {
flag = true;
} else {
flag = false;
}
} catch (Exception e) {
e.printStackTrace();
}
return flag;
}
@Override
protected void onPostExecute(Boolean aBoolean) {
dlg.dismiss();
}
}
위 코드를 간단하게 살펴보면 우선 아래 extends AsyncTask<String, Void, Boolean>은 AsyncTask를 확장한다는 뜻이고
<>사이에 있는 세가지 파라미터들은 각각의 의미를 살펴보자.
public class MyDownloadTask extends AsyncTask<String, Void, Boolean>
첫 번째는 doInBackground의 인풋 파라미터 타입을 의미한다.
세 번째는 onPostExecute의 리턴 타입 값을 의미한다.
다음으로 함수들을 살펴보면 함수 이름으로써 그 기능을 쉽게 유추 할 수 있다.
@Override
protected void onPreExecute() {
//doInBackground가 실행되기 전
dlg.show();
}
@Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
//doInBackground가 실행
}
@Override
protected void onPostExecute(Boolean aBoolean) {
//doInBackground가 실행된 후 결과처리!!!!
dlg.dismiss();
}
위 세 개의 함수는 doInBackground가 실행되기 전, 중, 후에 각각 실행되는 함수이며 최종적으로 doInBackground가 리턴한 값은 onPostExecute의 입력 파라미터로 들어간다.
이렇게 클래스를 만들어 놓고 원하는 액티비티에서 아래와 같이 호출해주면 에러 없이 실행이 됨을 확인할 수 있다.
new MyDownloadTask(mContext).execute("url");
'Android' 카테고리의 다른 글
[Android] 안드로이드 TextView에 html태그 그대로 적용하기 (0) | 2017.01.05 |
---|---|
[Android] AlertDialog 표시하기 (0) | 2016.12.09 |
[Android] 안드로이드 KeyEvent 2번 실행 방지 (0) | 2016.12.02 |
[Android] 안드로으드 툴바 메뉴 삭제하기 (0) | 2016.12.01 |
[Android] 안드로이드 Fragment replace할때 onCreate 다시그리기 방지하기 (1) | 2016.11.30 |