늦게 일어나서 저녁약속까지 있어서 오늘은 1시간 반정도 도서관 가서 코딩을 하였다.오늘은 첫메인페이지의 UI xml 디자인과 전체 table을 구성하는 데이타를 DB에 저장하고 이를 꺼낼 때 sorting하는 방법에 대해 고민해보았다. 그리고 어차피 이번 일은 앱을 만드는거도 있지만 공모전에 참여해서 좋은 성과를 내고자하는 목적도 있기에 내가 공모전에 가질 수 있는 강점과 약점에 대해서도 고민해보았다.

이 휴가철인 여름에 왠지 도서관에서 노트북으로 앱을 짜며 페이스북으로 많은 이들의 해수욕장 사진을 보니 왠지 약간 씁쓸해지도 했다. 하지만 다시 생각해보니 뭐 내가 해수욕장이나 바다를 좋아하는거도 아니고 남들 다 한다고 고생해서 내려가서 지내는거 보단 지금의 이 시원한 도서관에서 시원한 아메리카노 먹으며 내가 좋아하는 코딩해서 또한 다른 사람들이 유용하게 쓸 수 있는 앱을 만들어서 다른 사람 다운로드 받은 횟수보면서 좋아하는 게 나에게는 더 맞다는 생각이 들고 이게 고생이 아니라 나에게는 이게 더 행복한 일이라는 생각을 했다.

 그리고 어차피 이 일이 최종 목표가 공모전 입상이라면 나에게 강점과 약점을 분석해보기로 했다.

일단 강점은 나의 분석적인 능력이다. 분석력은 이어져서 일을 어쩌든지 완성시켜내는 능력으로 나온다. 일정을 고려하고 할 수 있는 분량을 정하고 그것을 할 수 있도록 나의 시간을 배정하고 또한 그걸 분해해서 나누어 일정계획을 잡아서 완성해나가는거,그리고 막히는 일이 생기면 다양한 방법으로 해결하고 정 안되면 괘도를 수정할 줄 아는 능력이 있다.

그리고 또하나 나에게는 산출물 작성의 능력이 있다. 이는 내가 봐선 아무래도 이 공모전에서 내가 내세워야할 부분이 아닌가 하는 생각을 한다. 프로그램을 만들어 나가면서 가졌던 이런 생각들도 모으고 또한 여러가지 요구분석단계의 문서 - 분석설계단계의 문서 - 코딩단계에서의 문서 - 테스트 단계의 문서를 모아써 제출한다면 앱결과물보다 좋은 결과 가 나오지 않을까 생각해본다.

나의 가장 큰 약점은 디자인,UI이다. 오늘도 하면서 느끼는 거지만 어째 고민하고 만지면 만질수록 더 망가지는 느낌이 든다. 그래서 이 부분은 어떻게 든지 외부에서 outsourcing을 해볼까한다.

이 또한 일을 완성하는 능력이겠지? 아자아자 잘 해보자꾸나

그리고 7월 향후 일정을 고민해보았는데 아직도 할게 많은데 너무 안이하게 일정을 맞출거라 했던 거같다.

아직 첫 메인화면 하나 나오고 있고 이거두 내일에는 데이타가 뿌려져서 낼쯤에나 완성이 될거다. 그럼 아직도 각 분야(교육,교통,문화)의 list화면이 더 있어야 하고 또한 상세화면해서 6개이상의 화면이 더 필요하다.

그리고 추가 기능도 생각해보아야 한다.(8월부터 해야할 기능이긴 하지만)

1) desing +UI

2) Search 기능

3) 변경 check기능 -> 후 작업

4) 다음 map api추가

5) 공사의 GPS현재위치로 찾고 위치별 sorting하는 거도 고민중이다

 

'프로그래밍 > 프로그래밍일지' 카테고리의 다른 글

7월 23일 프로그램일지  (0) 2013.07.23
7월 22일 프로그램 일지  (0) 2013.07.22
7월 18일 프로그램 일지  (0) 2013.07.18
7월 17일 프로그래밍 일지  (0) 2013.07.17
7월 13일 프로그램 일지  (0) 2013.07.13

드디어 다시 제 괘도에 올라온 듯 하다. 어제 좀 반성의 글을 올리고 수상도 하고나니 이제 좀 정신이 드나보다. 오늘은 전체 data를 담을 테이블의 structure를 잡고 테스트로 2개의 항목에 대한 데이터가 잘 들어가는 거까지 확인했다.이제 낼부터는 또 이 부분에 대한 노가다코딩을 해야징...

앱 제목을 '서울시가 궁금해?'로 했는데 어제 상을 받다보니 대상 제목이었다.헉 그 유명한 표절..그래서 급 이름을 다시 바꾸고 이름이 바뀌다보니 디자인 컨셉도 바뀌어 월/화/수는 정말 쓸데 없는 일이 되어 버렸다.

뭐 원래 프로그램이라는 게 항상 정해놓은 길로만 갈 수 있는 건 아니니 그 시간까지 감안해서 잡아둔 계획이니 그래도 다행이다.그래도 너무 안이하게 쉬엄쉬엄 가지는 말자꾸나.

'프로그래밍 > 프로그래밍일지' 카테고리의 다른 글

7월 22일 프로그램 일지  (0) 2013.07.22
7월 20일 프로그램 일지  (0) 2013.07.20
7월 17일 프로그래밍 일지  (0) 2013.07.17
7월 13일 프로그램 일지  (0) 2013.07.13
7월 11일 프로그래밍 일지  (0) 2013.07.11

지난 주말 도서관에 앉아서 대충 데이타를 다 받아서 DB에 넣는거까지 끝나고는 그럭저럭 3일을 보내버렸다. 잘 되지도 않는  UI,디자인 신경쓴다며 일러스트레이터에 xml UI 디자인 책을 보며 노력해보았으나 디자인은 좀 내가 할 영역은 아닌거 같다. 그리고 아직도 내가 해야 할 코딩이 많은데 끝난거 처럼 이렇게 보내서는 안된다.

오늘은 그 이전에 했던 앱의 노력의 결과로 얻는 성과가 한꺼번에 2개나 온 날이 되었다.

이렇게 존경하는 박원순 서울시장님에게 오늘 상도 받은 날이 되었고

 

회사 사보에도 나와 널리 이름을 날리기도 했다. 하지만 프로그래머가 프로그램으로 상을 받기보다는 프로그램을 만들며 이야기로 상을 받은 건 좀 아쉽기 때문에 이번에는 공모전에서 좋은 앱으로 상을 제대로 받아보리라.

다시 한번 맘을 다잡고 열심히 해보자 꾸나 그래도 다행인 것은 오늘은 지난주 계획했던 운동은 했다는 사실이다. 좀더 고삐를 당겨서 열심히 해야겠다

'프로그래밍 > 프로그래밍일지' 카테고리의 다른 글

7월 20일 프로그램 일지  (0) 2013.07.20
7월 18일 프로그램 일지  (0) 2013.07.18
7월 13일 프로그램 일지  (0) 2013.07.13
7월 11일 프로그래밍 일지  (0) 2013.07.11
7월 10일 프로그램 일지  (0) 2013.07.10

주말인데도 많이 코딩하지 못하고 이렇게 이제야 자리에 앉았다. 나의 징크스중 하나는 코딩을 노가다로 해야하는 경우가 생기면 이상하게 진도를 못 내고 거기서 몇일을 보낸다. 목요일부터 xml parsing하는 문제에서 노가다 말고 좋은 방법을 찾고자 여러가지 방법으로 구현해보고 코딩해보았으나 역시나 이전 방법으로 가기로 결정하고는 어제 오늘 이게 맞나 싶어서 진도가 안 나간다. 어차피 더 좋은 방법이 있다하더라도 내 능력으로 할 수 있는게 거기까지면 그걸 선택하고 진행해야하거늘 그게 쉽지 않다.

지난 금요일부터 다시 오른쪽 어깨가 아파서 오늘 다시 목욕탕에서 마사지를 받았다. 아무래도 코딩에만 신경써서는 안 될 듯 하다. 나름 일주일에 철저한 계획을 세워봐야겠다. 일주일에 3번 정도는 헬스를 다니고 2일정도는 코딩을 해야지

화,목은 헬스 월,수,금은 코딩을 해야지 물론 하루정도는 쉬는걸로 해서 ... 토요일 일요일중 하루는 헬스 그리고 주말은 5시간정도 집중코딩을 하리라...

과연 이렇게 해도 될까 말까다 사실... 좀더 집중해서 해보자꾸나.

 

'프로그래밍 > 프로그래밍일지' 카테고리의 다른 글

7월 18일 프로그램 일지  (0) 2013.07.18
7월 17일 프로그래밍 일지  (0) 2013.07.17
7월 11일 프로그래밍 일지  (0) 2013.07.11
7월 10일 프로그램 일지  (0) 2013.07.10
7월 9일 프로그램 일지  (0) 2013.07.09

사실 오늘 퇴근하기 전까지는 테마가 XML PARSING이었다. 기존의 로직으로 짜놓은 파싱방법은 이 프로그램에 적용하기에는 너무 노가다가 많다. 그래서 회사내에서도 시간이 나면 인터넷 검색을 하면서 찾아보았는데 지금은 고민이 되긴 하다. 회사에서 책을 읽을 수 있는 여유가 생겨서 지금 책을 읽고 공부할 수 있어서 고민이 되긴 하지만 그렇다고 다른 걸 하기에는 또 흐름이 끊어지기에 일단 책을 보고 XML에 대해 공부해보자.... 내일은 다른 책을 봐도 되잖아.

사실 어제는 거의 data structure 잡느라 거의 노가다성 일이 많았고 파싱하는데 걸려서 그리 만족적이진 않은 작업이었다.

그리고 이 앱을 만들면 가장 큰 고민은 너무나도 큰 데이타의 양이다. 그러하여 3가지정도의 고민이 나온다.

1) 변경되었는지 어떻게 알것이냐?

2) 변경된 데이타가 무엇이냐?

3) 이 2만건 가까이 되는 데이타를 과연 받는데 얼마나 걸릴것이며 이를 보완할 방법은 무엇인가?

쉽지않은 작업이며 이런 고민이 잘 해결되길 빌어보고 열심히 고민중이다.

오늘도 이시간에 자리에 앉았다. 어제는 좀 많이 피곤해서 1시간정도의 시간동안 밖에 코딩을 못 해서 각 서비스의 count 저장 하는 정도를 하고 일찍 잤다. 오늘은 2시간정도는 작업을 했음 좋겠다. 7월내에는 프로토타입을 만들고 8월에는 UI와 디자인을 입힐 생각으로 지금 계획을 잡고있다.

 

9시 30분 퇴근하여 밥을 해먹고 이제 겨우 자리에 앉아서 냉커피 한잔과 함께eclipse를 띄웠다. 시간이 많지 않아 매일 많은 시간을 소요해서 일지를 적을 수 있을지는 모르겠지만 일단 최대한 노력해볼련다. 왜냐하면 프로그램을 만드는거도 재미있지만 글로 남겨서 기록해두는 행위 또한 내가 너무나 좋아하는 일이기에

고객사 정책상 노트북을 회사내로 가져갈 수 없기 때문에 이렇게 노트 코딩을 이제부터는 해보려고 한다. 오늘 짜야 할 분량을 생각해서 그 안에서의 로직을 고민해보고 필요한 기술요소 필요한 자료를 준비함으로서 집에서 책상에 앉아서 코딩하는 부분을 최소화하고 가장 효율적으로 해보고자 한다.

 

몇달 회사내에서 이동도 있고 자리를 잡느라 손을 놓았던 프로그램을 이제 다시 시작하려고 주말에 책도 읽고 도서관에서 가서 생각도 하면서 이제 겨우 컨셉을 잡아간다. 저번 공공앱 스토리텔링으로 공모전에서 상도 받고 보니 이번에는 9월 17일까지 있게되는 공모전에 퇴근해서 짬짬이 주말에 준비하여 도전해 볼까한다.

 

나의 작업공간은 이렇게 노트북 2대로 확보해두고

아마도 주제는 '서울시가 궁금해?'라는 주제로 서울시에서 열리는 각종 문화행사, 교육,교통사고을 볼 수 있는 앱을 만들어볼려고 한다. 오늘부터 작업하려고 하니 이런이런 오후10시까지는 서울시 열린광장이 시스템 점검중이라니 이렇게 시간을 보내며 정리의 시간을 갖는다.

서비스명
대분류 개수
건설알림이 교통 522
교육공공서비스예약정보 교육 9793
교육정보 교육 209
교통돌발상황조회 교통 817
도서관강좌교육정보 교육 2060
문화행사공공서비스예약정보 문화 76
문화행사정보 문화 212
서울시여성능력개발원교육강좌 교육 54
용산여성인력개발센터교육강좌 교육 21
중랑여성인력개발센터교육강좌 교육 43
중부여성발전센터교육강좌 교육 97
지하철예술무대공연일정 문화 19479

'프로그래밍 > 프로그래밍일지' 카테고리의 다른 글

7월 17일 프로그래밍 일지  (0) 2013.07.17
7월 13일 프로그램 일지  (0) 2013.07.13
7월 11일 프로그래밍 일지  (0) 2013.07.11
7월 10일 프로그램 일지  (0) 2013.07.10
7월 9일 프로그램 일지  (0) 2013.07.09

AsyncTask는 이전 글인 [안드로이드]AsyncTask에 대하여...(전체소스포함) 에서 설명을 했으며 Thread에 대해서는 저의 다음블로그에서 자바 스레드(Threads)에 대해(http://blog.daum.net/dayhyub/56)에서 이야기를 했는데 기본적인 안드로이드 Thread의 이야기만 조금만 더 해보고 프로그래스바 구현 두개의 소스로 비교를 해보도록 하겠습니다.

Thread의 정의

● 프로세스보다 작은 단위이기 때문에 프로세스보다 가볍다.

● Thread는 서로의 자원을 공유하면서 동작한다.

● 한꺼번에 여러개의 작업을 동시에 실행할 때 사용된다.

Thread생성방법

● Thread클래스를 상속하는 방법

● Runnable인터페이스를 구현하는 방법

(1) Progressbar구현을 위해 함수 call방법비교

● Thread

startProgressBarThread2(); 

● AsyncTask

new ImageCallTask().execute(limgurl);
(2) Progressbar구현 사전 준비

● Thread

	// 막대형 진행상자//////////////////////////
	public ProgressDialog progressDialog;
	private volatile Thread theProgressBarThread2;
	
	public synchronized void startProgressBarThread2() {
		if (theProgressBarThread2 == null) {
			theProgressBarThread2 = new Thread(null, backgroundTread2,
					"startProgressBarThread2");
			theProgressBarThread2.start();

			progressDialog = new ProgressDialog(act);
			progressDialog.setCanceledOnTouchOutside (false);
			progressDialog.setCancelable(false);
			progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
			progressDialog.setMessage("최신데이타로 업데이트중입니다.잠시만 기다리십시요 ...");
			progressDialog.incrementProgressBy(1);
			progressDialog.setMax(100);
			progressDialog.setProgress(0);
			progressDialog.show();
		}
	}

● AsyncTask

		private ProgressDialog dialog;
		
		// 이곳에 포함된 code는 AsyncTask가 execute 되자 마자 UI 스레드에서 실행됨.
		// 작업 시작을 UI에 표현하거나
		// background 작업을 위한 ProgressBar를 보여 주는 등의 코드를 작성.
		@Override
		protected void onPreExecute() {
	           // 작업을 시작하기 전 할일
	        dialog = new ProgressDialog(DetailActivity.con);
	        dialog.setTitle("이미지 다운로드중");
	        dialog.setMessage("잠시만 기다리세요...");
	        dialog.setIndeterminate(true);
	        dialog.setCancelable(true);
	        dialog.show();
	        			
			super.onPreExecute();
		}	
(3) Progressbar구현 작업

● Thread

	private Runnable backgroundTread2 = new Runnable() {
		@Override
		public void run() {
			if (Thread.currentThread() == theProgressBarThread2) {
				int prate= (int)(100/AString.length);
			    for(int i =0; i < AString.length;i++){
					DataInfo[] datainfo3 = new DataInfo[PublicCall.datacnt];
					String url="http://openapi.seoul.go.kr:8088/6461656879756232303536/xml/ListLostArticleService/1/"+DATACALL+"/"+AString[i];
					datainfo3 = PublicCall.publiccall(url,DATACALL);
					InsertCall.insertcall(datainfo3);
					//Log.d(TAG,"InsertCall :["+i+"]prate=["+prate+"]");
					if(i == (AString.length-1)) progressrate = 100;
					else progressrate = (int)(prate*(i+1));
					progressBarHandle2.sendMessage(progressBarHandle2
							.obtainMessage());					
				}	
			}
		}

● AsyncTask

				@Override
		protected Bitmap doInBackground(String... urls) {
			/* http://snowbora.com/417 참고 
			 * http://android-developers.blogspot.kr/2010/07/multithreading-for-performance.html
			 * */
			final HttpClient client			= AndroidHttpClient.newInstance("Android");
	        final HttpGet getRequest 		= new HttpGet(urls[0]);
	        final int IMAGE_MAX_SIZE 		= 1280;
	        
	        try 
	        {
	            HttpResponse response = client.execute(getRequest);
	            final int statusCode = response.getStatusLine().getStatusCode();
	            
	            if (statusCode != HttpStatus.SC_OK) 
	            {
	                return null;
	            }

	            final HttpEntity entity = response.getEntity();
	            
	            if (entity != null) 
	            {
	                InputStream inputStream = null;
	                
	                try 
	                {
	                	inputStream = entity.getContent();
	                	
	                	BitmapFactory.Options bfo 	= new BitmapFactory.Options();
	                	bfo.inJustDecodeBounds 		= true;

	                    BitmapFactory.decodeStream(new FlushedInputStream(inputStream), null, bfo);
	                    
	                    if(bfo.outHeight * bfo.outWidth >= IMAGE_MAX_SIZE * IMAGE_MAX_SIZE)
	                    {
	                    	bfo.inSampleSize = (int)Math.pow(2, (int)Math.round(Math.log(IMAGE_MAX_SIZE / (double) Math.max(bfo.outHeight, bfo.outWidth)) / Math.log(0.5)));
	                    }
	                    bfo.inJustDecodeBounds = false;
	                    
	                    response = client.execute(getRequest);
	                    final int nRetryStatusCode = response.getStatusLine().getStatusCode();
	                    
	                    if (nRetryStatusCode != HttpStatus.SC_OK) 
	                    {
	                        return null;
	                    }
	                    
	                    final HttpEntity reEntity = response.getEntity();
	                    
	                    if (reEntity != null)
	                    {
	                    	InputStream reInputStream = null;
	                    	
	                    	try
	                    	{
	                    		reInputStream = reEntity.getContent();
	                    		final Bitmap imgBitmap = BitmapFactory.decodeStream(new FlushedInputStream(reInputStream), null, bfo);
	                            
	                            return imgBitmap;
	                    	}
	                    	finally 
	                        {
	                    		 if (reInputStream != null) 
	                             {
	                    			 reInputStream.close();
	                             }
	                    		 
	                    		 reEntity.consumeContent();
	                        }
	                    }
	                } 
	                finally 
	                {
	                    if (inputStream != null) 
	                    {
	                        inputStream.close();
	                    }
	                    
	                    entity.consumeContent();
	                }
	            }
	        } 
	        catch (IOException e) 
	        {
	            getRequest.abort();
	        } 
	        catch (IllegalStateException e) 
	        {
	            getRequest.abort();
	        } 
	        catch (Exception e) 
	        {
	            getRequest.abort();
	        } 
	        finally 
	        {
	            if ((client instanceof AndroidHttpClient)) 
	            {
	                ((AndroidHttpClient)client).close();
	            }
	        }
	        
	        return null;
	        
	    }	
(4) Progressbar작업진행상태 표시

● Thread

Handler progressBarHandle2 = new Handler() {
			@Override
			public void handleMessage(Message msg) {
				
				progressDialog.setProgress(progressrate);
				progressDialog.setMessage("데이타를 저장중입니다.잠시만 기다리십시요 ..."
						+ progressrate + "%");
				if (progressrate == 100) {
					stopProgressBarThread2();
					datainfo = selectData();
					appendRowFirst(datainfo);					
				}
			}
		};

● AsyncTask

// onInBackground(...)에서 publishProgress(...)를 사용하면
		protected void onProgressUpdate(Integer... progress) {
			Log.d("LOST","onProgressUpdate:["+progress[0]+"]");
			dialog.setProgress(progress[0]);
		}
		
(5) Progressbar작업 완료 작업

● Thread

public synchronized void stopProgressBarThread2() {
		if (theProgressBarThread2 != null) {
			Thread tmpThread = theProgressBarThread2;
			theProgressBarThread2 = null;
			tmpThread.interrupt();
		}
		if (progressDialog != null)
			progressDialog.dismiss();
	}

● AsyncTask

// onInBackground(...)가 완료되면 자동으로 실행되는 callback
		// 이곳에서 onInBackground가 리턴한 정보를 UI위젯에 표시 하는 등의 작업을 수행함.
		// (예제에서는 작업에 걸린 총 시간을 UI위젯 중 TextView에 표시함)
		@Override
		protected void onPostExecute(Bitmap imgBitmap) {
			if (imgBitmap != null)
			{
				imgView.setImageBitmap(imgBitmap);
				imgView.setVisibility(ImageView.VISIBLE);
				textview.setVisibility(TextView.GONE);
			}else{
				//textview = (TextView)findViewById(R.id.textView1);
				textview.setText("등록된 사진이 없습니다.");
				textview.setTextSize(20);
				textview.setGravity(Gravity.CENTER_VERTICAL | Gravity.CENTER_HORIZONTAL);
				textview.setVisibility(TextView.VISIBLE);
				imgView.setVisibility(ImageView.GONE);
			}
		
			dialog.dismiss();
		}

AsyncTask를 이야기하려다 보니 프로그래스바 하나 넣어보겠다고 3~4일을 고생해서 겨우 찾아냈던 기억이 새록새록하면서 애증이 담겨있는 class라는 생각이 듭니다. 하지만 AsyncTask는  thread+handler라는 나름 강력한 기능을 가지고 있어서 제대로만 알아두면 유용한 클래스가 되지 않을까 싶습니다.

혹시 책만 보고 도전했다가 저같이 고생하지 않았으면 하는 맘에 이 글을 적어봅니다.

왜 AsyncTask인가?

AsyncTask라는 클래스 이름은 Asynchronous Task의 줄임이며, UI스레드의 입장에서 볼 때 비동기적으로 작업이 수행되기 때문에 붙여진 이름이다.

sync 와 async의 용어는 네트워크이나 커널 프로세스에서 많이 나오는 용어인데요.저야 뭐 이론적으로는 공부한지 하도 오래되어서 그냥 프로그램 하면서 경험으로 이야기를 해보겠습니다.

보통 sync는 직렬회로라고 보시면 될듯합니다. 반면 async는 병렬회로라고 보시면 될 듯 합니다.

일이 순차적으로 진행되면서 하나가 해결되면 그다음 일이 진행되는 식으로 네트워크에서는 요청(request)를 보내면 항상 응답(response)을 받아야 진행하는 방식으로 구현하면 sync방식,아니고 계속 요청을 보내는 통로와 응답을 받는 통로를 따로 만들어두면 async방식이라고 불리죠.

AsyncTask는 UI 처리 및 Background 작업 등 을 하나의 클래스에서 작업 할 수 있게 지원해 줍니다. 쉽게말해 메인Thread와 일반Thread를 가지고 Handler를 사용하여 핸들링하지 않아도 AsyncTask 객체하나로 각각의 주기마다 CallBack 메서드가 편하게 UI를 수정 할 수 있고, Background 작업을 진행 할 수 있습니다.

AsyncTask사용법

Object로부터 상속하는 AsyncTask는 Generic Class이기 때문에 사용하고자 하는 type을 지정해야 합니다.
AsyncTask클래스는 기본적으로 3개의 제네릭 타입(Params,Progress,Result)을 제공하고 있는 추상 클래스다.Generic type은 실행시간에 데이터 타입을 정할 수 있는 특수한 타입이라고 이해하시면 될 듯 합니다.

Params: background작업 시 필요한 data의 type 지정
Progress: background 작업 중 진행상황을 표현하는데 사용되는 data를 위한 type 지정
Result: 작업의 결과로 리턴 할 data 의 type 지정

예)

AsyncTask<DataInfo[], Integer, Void> InsertTask = new InsertCallTask().execute(datainfo4);

미사용 타입에 대해서는 Void를 전달하면 된다.  

AsyncTask Callbak 함수

언제 호출되여 무슨 작업을 하는가와 함께 각 메서드가 어떤 스레드에서 실행되는가도 중요하다. doInBackground메서드 외에는 모두 UI스레드에서 실행되므로 메인스레드의 view들을 안전하게 참조할 수 있습니다.

주로 쓰게 되는 콜백메스드 4개에 대해 설명해보겠습니다.

● void onPreExecute()

작업이 시작되기 전에 호출되며 UI스레드에서 실행되는 메소드,계산을 위한 초기화나 프로그래스 대화상자를 준비하는 등의 작업을 수행합니다.

		// 이곳에 포함된 code는 AsyncTask가 execute 되자 마자 UI 스레드에서 실행됨.
		// 작업 시작을 UI에 표현하거나
		// background 작업을 위한 ProgressBar를 보여 주는 등의 코드를 작성.
		@Override
		protected void onPreExecute() {
	           // 작업을 시작하기 전 할일
	        dialog = new ProgressDialog(DetailActivity.con);
	        dialog.setTitle("이미지 다운로드중");
	        dialog.setMessage("잠시만 기다리세요...");
	        dialog.setIndeterminate(true);
	        dialog.setCancelable(true);
	        dialog.show();
	        			
			super.onPreExecute();
		}	

Result doInBackground(Params... params)

백그라운드 스레드로 동작해야 하는 작업을 실행한다. execute메서드로 전달한 data tye이 params 인수로 전달되는데 여러개의 인수를 전달할 수 있으므로 배열 타입으로 되어 있습니다. 그래서 하나의 인수만 필요하다면 params[0]만 사용하면 됩니다. 작업 중에 publishProgress 메소드를 호출하여 작업 경과를 UI스레드로 display할 수 있으며 작업결과는 Result타입으로 리턴됩니다.

		@Override
		protected Bitmap doInBackground(String... urls) {
			/* http://snowbora.com/417 참고 
			 * http://android-developers.blogspot.kr/2010/07/multithreading-for-performance.html
			 * */
			final HttpClient client			= AndroidHttpClient.newInstance("Android");
	        final HttpGet getRequest 		= new HttpGet(urls[0]);
	        final int IMAGE_MAX_SIZE 		= 1280;
	        
	        try 
	        {
	            HttpResponse response = client.execute(getRequest);
	            final int statusCode = response.getStatusLine().getStatusCode();
	            
	            if (statusCode != HttpStatus.SC_OK) 
	            {
	                return null;
	            }

	            final HttpEntity entity = response.getEntity();
	            
	            if (entity != null) 
	            {
	                InputStream inputStream = null;
	                
	                try 
	                {
	                	inputStream = entity.getContent();
	                	
	                	BitmapFactory.Options bfo 	= new BitmapFactory.Options();
	                	bfo.inJustDecodeBounds 		= true;

	                    BitmapFactory.decodeStream(new FlushedInputStream(inputStream), null, bfo);
	                    
	                    if(bfo.outHeight * bfo.outWidth >= IMAGE_MAX_SIZE * IMAGE_MAX_SIZE)
	                    {
	                    	bfo.inSampleSize = (int)Math.pow(2, (int)Math.round(Math.log(IMAGE_MAX_SIZE / (double) Math.max(bfo.outHeight, bfo.outWidth)) / Math.log(0.5)));
	                    }
	                    bfo.inJustDecodeBounds = false;
	                    
	                    response = client.execute(getRequest);
	                    final int nRetryStatusCode = response.getStatusLine().getStatusCode();
	                    
	                    if (nRetryStatusCode != HttpStatus.SC_OK) 
	                    {
	                        return null;
	                    }
	                    
	                    final HttpEntity reEntity = response.getEntity();
	                    
	                    if (reEntity != null)
	                    {
	                    	InputStream reInputStream = null;
	                    	
	                    	try
	                    	{
	                    		reInputStream = reEntity.getContent();
	                    		final Bitmap imgBitmap = BitmapFactory.decodeStream(new FlushedInputStream(reInputStream), null, bfo);
	                            
	                            return imgBitmap;
	                    	}
	                    	finally 
	                        {
	                    		 if (reInputStream != null) 
	                             {
	                    			 reInputStream.close();
	                             }
	                    		 
	                    		 reEntity.consumeContent();
	                        }
	                    }
	                } 
	                finally 
	                {
	                    if (inputStream != null) 
	                    {
	                        inputStream.close();
	                    }
	                    
	                    entity.consumeContent();
	                }
	            }
	        } 
	        catch (IOException e) 
	        {
	            getRequest.abort();
	        } 
	        catch (IllegalStateException e) 
	        {
	            getRequest.abort();
	        } 
	        catch (Exception e) 
	        {
	            getRequest.abort();
	        } 
	        finally 
	        {
	            if ((client instanceof AndroidHttpClient)) 
	            {
	                ((AndroidHttpClient)client).close();
	            }
	        }
	        
	        return null;
	        
	    }

void onProgressUpdate(Progress... values)

doInBackground에서드에서 publishProgress(Progress...) 메소드를 호출할 때 호출되며 작업의 진행사항을 표시하기 위해 호출됩니다. UI스레드에서 프로그래스바에 진행 상태 표시하는 역할 수행합니다.

		// onInBackground(...)에서 publishProgress(...)를 사용하면
		protected void onProgressUpdate(Integer... progress) {
			Log.d("LOST","onProgressUpdate:["+progress[0]+"]");
			dialog.setProgress(progress[0]);
		}

 

void onPostExecute(Result result)

doInBackground에서드의 작업 결과를 UI반영하는 역할을 담당하는 메소드입니다.

		// onInBackground(...)가 완료되면 자동으로 실행되는 callback
		// 이곳에서 onInBackground가 리턴한 정보를 UI위젯에 표시 하는 등의 작업을 수행함.
		// (예제에서는 작업에 걸린 총 시간을 UI위젯 중 TextView에 표시함)
		@Override
		protected void onPostExecute(Bitmap imgBitmap) {
			if (imgBitmap != null)
			{
				imgView.setImageBitmap(imgBitmap);
				imgView.setVisibility(ImageView.VISIBLE);
				textview.setVisibility(TextView.GONE);
			}else{
				//textview = (TextView)findViewById(R.id.textView1);
				textview.setText("등록된 사진이 없습니다.");
				textview.setTextSize(20);
				textview.setGravity(Gravity.CENTER_VERTICAL | Gravity.CENTER_HORIZONTAL);
				textview.setVisibility(TextView.VISIBLE);
				imgView.setVisibility(ImageView.GONE);
			}
		
			dialog.dismiss();
		}
		

일반적으로 AsyncTask를 구현할 때 별도 스레드로 동작해야 할 코드는 doInBackground()메소드에 작성하고, 이 메소드가 실행되기 전에 먼저 처리할 코드가 있다면 onPreExecute()메소드에 작성하면 됩니다. 그리고 doInBackground()메소드가 완료된 후에 처리해야할 코드는 onPostExecute()메소드에 작성하고, doInBackground()메소드가 동작하는 동안 주기적으로 반영해야 할 작업이 있다면 onProgressUpdate()메소드에 작성하면 됩니다.

이 때 주의사항은 3개의 제네릭 타입과 메소드 타입을 잘 맞춰어야 원하는 결과가 나온다는 겁니다.이게 잘 안 맞아서 저는 코딩하면서 구현이 제대로 안되고 한참 고생했던 기억이 있습니다. 꼭 doInBackground, onPreExecute, onPostExecute의 리턴값과 파라미터를 잘 매칭해야 합니다.

 

참고사이트

+ Recent posts