이미지를 로딩하거나 외부데이터베이스의 데이터를 로딩하는 등의 오래걸리는 작업을 수행할 때 사용자가 앱이 멈춘것이 아니라는 것을 인지시키기 위해 ProgressDialog를 사용하게 됩니다. 이 ProgressDialog에는 두가지 모양의 Progress가 가능합니다.
1. 로딩할 데이터의 양이 얼마인지 몰라 현재 얼마만큼 작업이 수행된건지 측정할 수 없을 때 사용하는 둥근 형태의 SPINNER 스타일.
2. 로딩할 데이터의 양이 얼마인지 알고있어서 현재 작업수행정도를 표시할 수 있을 때 사용하는 막대바 형태의 HORIZONTAL 스타일.
이 중 막대바형태의 ProgressDialog 를 진행시키기 위해서는 별도의 Thread를 사용해야만 합니다. 이때 별도의 Thread에서 Progress를 진행하는 것은 어렵지 않지만 주의할 점은 화면(UI)은 오로지 main(UI) Thread 만 변경이 가능하다는 것입니다. 그렇기에 별도의 작업스레드에서 진행상황을 변경하는 명령을 수행할 수 없어서 runOnUiThread() 메소드를 호출하거나 Handler를 이용하여 UI를 변경하는 작업을 수행해야 합니다. 이는 다소 불편하게 느껴질수 있습니다. 그래서 별도의 Thread 작업과 UI 작업을 한번에 할 수 있는 AsyncTask 클래스를 이용해서 막대바 형태의 ProgressDialog를 실행시키는 앱을 소개합니다.
버튼을 누르면 0.1초(100ms) 간격으로 ProgressDialog가 진행되고 끝마치면 Toast를 표시하는 예제 앱 소스입니다.
메인화면 버튼클릭시 나타나는 ProgressDialog Progress 종료후 Toast 완료 메세지
Layout 파일
activity_main.xml |
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="${relativePackage}.${activityClass}" > <Button android:id="@+id/button" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Progress Dialog by AsyncTask" android:onClick="mOnClick"/> </RelativeLayout> |
소스파일
MainActivity.java |
public class MainActivity extends Activity {
ProgressDialog dialog; //ProgressDialog 참조변수 int pos_dilaog=0; //ProgressDialog의 진행 위치 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); }
//Button 클릭시에 자동으로 호출되는 callback Method... public void mOnClick(View v){
switch( v.getId() ){
case R.id.button:
if(dialog!=null) return; //ProgressDialog가 현재 보여지고 있다면 아무작업도 하지 않음.
new AsyncProgressDialog().execute(100); // 다이얼로그의 max 값으로 100 전달
break; }
}
//AsyncTask를 상속한 클래스선언 //AsyncTask 클래스의 콜백 메소드들 중 doInBackground를 제외하고는 기본적으로 main(UI) Thread에서 실행됨. //doInBackground를 제외한 다른 메소드에서는 어디서든 UI 작업 가능
//AsyncTask< 작업스레드가 처리할 데이터 타입 , 다이얼로그의 설정 데이터 타입, 작업의 결과로 리턴할 데이터 타입 > //쉽게 소개하면 //첫번재 데이터 타입은 doInBackground() 메소드의 파라미터 타입을 지정 //두번재 파라미터의 타입은 onProgressUpdate() 메소드의 파라미터 타입을 지정 //세번째 파라미터의 타입은 onPostExecute() 메소드의 파라미터 타입을 지정 class AsyncProgressDialog extends AsyncTask<Integer, Integer, String>{
//작업이 시작되기 전에 호출되는 메소드로서 일반적으로 이곳에서 ProgressDialog 객체를 생성. @Override protected void onPreExecute() { // TODO Auto-generated method stub super.onPreExecute();
dialog= new ProgressDialog(MainActivity.this); //ProgressDialog 객체 생성 dialog.setTitle("Progress"); //ProgressDialog 제목 dialog.setMessage("Loading....."); //ProgressDialog 메세지 dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); //막대형태의 ProgressDialog 스타일 설정 dialog.setCanceledOnTouchOutside(false); //ProgressDialog가 진행되는 동안 dialog의 바깥쪽을 눌러 종료하는 것을 금지
dialog.show(); //ProgressDialog 보여주기 }
//excute() 메소드에 의해 실행되는 작업 스레드의 메소드 ( excute()호출 시에 전달한 값 params에서 받음 ) @Override protected String doInBackground(Integer... params) { // TODO Auto-generated method stub
while( pos_dilaog < params[0]){ //현재 ProgessDialog의 위치가 100보다 작은가? 작으면 계속 Progress
pos_dilaog++;
//ProgressDialog에 변경된 위치 적용 .. publishProgress(pos_dilaog); //onProgressUpdate()메소드 호출.
try { Thread.sleep(100); //0.1초간 스레드 대기 ..예외처리 필수 } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); }
}//while
//while을 끝마치고 여기까지 오면 Progress가 종료되었다는 것을 의미함. pos_dilaog=0; //다음 프로세스를 위해 위치 초기화
return "Complete Load"; // AsyncTask 의 작덥종료 후 "Complete Load" String 결과 리턴 }
//publishProgress()에 의해 호출되는 메소드 @Override protected void onProgressUpdate(Integer... values) { // TODO Auto-generated method stub super.onProgressUpdate(values);
dialog.setProgress(values[0]); //전달받은 pos_dialog값으로 ProgressDialog에 변경된 위치 적용 }
//doInBackground() 메소드 종료 후 자동으로 호출되는 콜백 메소드 //doInBackground() 메소드로부터 리턴된 결과를 파라미터로 받음 @Override protected void onPostExecute(String result) { // TODO Auto-generated method stub super.onPostExecute(result);
dialog.dismiss(); //ProgressDialog 보이지 않게 하기 dialog=null; //참조변수 초기화
//doInBackground() 메소드로부터 리턴된 결과 "Complete Load" string Toast로 화면에 표시 Toast.makeText(MainActivity.this, result, Toast.LENGTH_SHORT).show(); }
}//AsyncProgressDailog class.. }//MainActivity class.. |
'소소한 소스코드' 카테고리의 다른 글
[안드로이드 Android] 옵션메뉴(Option Menu)와 액션바 메뉴(ActionBar Menu) (0) | 2015.06.03 |
---|---|
[안드로이드 Android] 시스템 인텐트(Intent)를 이용한 전화걸기, 문자보내기, 이메일보내기 etc (0) | 2015.05.29 |
Android 채팅 앱 - 간단한 단말기 간 소켓통신 (12) | 2015.04.14 |
Android Notification 확인하기 (PendingIntent 적용) (0) | 2015.03.30 |
Android 상태표시줄에 알림 만들기 Notification (0) | 2015.03.30 |