안녕하세요..
실은 제가 하고자 하는 내용이..데이터베이스에서 데이터를 조회하는 동안 데이터 조회중이라는 ProgressDialog를 띄우는데요..
이 ProgressDialog에 취소 버튼이 있어서 취소 버튼을 클릭하면 데이터를 조회하는 스레드를 종료하는 작업으로 진행하고 싶습니다..
그래서 다음과 같은 코딩을 했습니다..
이것은 Activity의 onCreateDialog 함수에서 해당 ProgressDialog를 띄울때의 코드입니다. 물론 showDialog(SearchDialog)로 호출하고 있구요..
제가 Dialog를 생성하는 클래스를 별도로 만들어서(MakeDialog란 클래스입니다) 그 클래스 객체를 생성한뒤 makeProgressDialog 함수를 호출해서 ProgressDialog를 만들어서 작업하고 있습니다..
case SearchDialog :
DialogInterface.OnClickListener click = new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
Log.d("BookmarkList", "Progress Dialog Cancel 클릭");
selectThread.interrupt();
handler.removeMessages(1);
// dialog.dismiss();
removeDialog(BookmarkList.SearchDialog);
}
};
DialogInterface.OnCancelListener cancel = new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
// TODO Auto-generated method stub
Log.d("BookmarkList", "Progress Dialog Cancel Listener 작동");
selectThread.interrupt();
handler.removeMessages(1);
// dialog.dismiss();
removeDialog(BookmarkList.SearchDialog);
}
};
// progressdialog = new MakeDialog().makeProgressDialog(this, "즐겨찾기 조회", "즐겨찾기 조회중입니다", false, "취소", click);
progressdialog = new MakeDialog().makeProgressDialog(this, "즐겨찾기 조회", "즐겨찾기 조회중입니다", true, "취소", click, cancel);
return progressdialog;
그리고 MakeDialog 클래스의 makeProgressDialog 함수는 다음과 같이 정의되어 있습니다..
이 함수에서는 단순히 ProgressDialog를 입력받은 파라미터값에 맞춰서 만들고 있습니다
public ProgressDialog makeProgressDialog(Context context, String title, String message, boolean cancelable, String buttontitle, DialogInterface.OnClickListener click, DialogInterface.OnCancelListener cancel){
ProgressDialog objDialog = new ProgressDialog(context);
objDialog.setTitle(title); // ProgressDialog 의 제목
objDialog.setMessage(message); // ProgressDialog 의 내용
objDialog.setCancelable(cancelable);
if(!(("".equals(buttontitle)) || (buttontitle == null))){
objDialog.setButton(buttontitle, click);
}
if(cancel != null){
objDialog.setOnCancelListener(cancel);
}
return objDialog;
}
ProgressDialog를 만드는 부분은 이렇구요..이것을 호출하는 부분은 다음과 같이 되어있습니다..검색 버튼을 클릭하면 ProgressDialog를 생성하고Thread를 같이 만들어서 실행하고 있구요..
보시면 showDialog(SearchDialog)를 통해서 ProgressDialog를 띄우고 있구요..그 담으로 사용자가 입력한 값을 받아서 DBSelectThread 객체를 생성해서 거기에 넘겨준뒤 start를 호출하고 있습니다. DBSelectThread는 Thread를 상속 받은 상태입니다.
btnSearch.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
showDialog(SearchDialog);
Company objCompany = (Company)(selCompany.getItemAtPosition(selCompany.getSelectedItemPosition()));
String invoiceno = ((EditText)findViewById(R.id.invoiceno)).getText().toString();
String title = ((EditText)findViewById(R.id.bookmarktitle)).getText().toString();
c = null;
selectThread = new DBSelectThread(service, 1, handler);
selectThread.setCompanyid(objCompany.companyno);
selectThread.setInvoiceno(invoiceno);
selectThread.setTitle(title);
selectThread.setDaemon(true);
selectThread.start();
}
});
ProgressDialog에서 취소 버튼을 눌르면 DBSelectThread에서 작업하던것을 중지해야 하기땜에 다음과 같이 했습니다..
DBSelectThread에서 interrupt 함수를 재정의했는데요..
bookmarklist는 Cursor입니다. Thread에서 데이터베이스를 조회해서 Cursor를 메인 Activity에 있는 Handler에 메시지 형태로 전달하고 있습니다
public void interrupt() {
// TODO Auto-generated method stub
Log.d("BookmarkList", "interrupt 실행");
// service.close();
bookmarklist = null;
super.interrupt();
}
DBThread의 run 함수는 다음과 같이 재정의했습니다. 제가 별도 작업용 객체인 service객체에서 데이터베이스를 조회하도록 해서 그 결과로 Cursor 객체가 리턴이 되도록 했습니다. 그래서 리턴받은 Cursor를 핸들러의 메시지에 넣어서 하도록 했습니다. 그 부분이 제가 굵은 글씨체로 표현한 부분입니다. 그래서 핸들러에서 메시지를 받아 메시지에서 Cursor를 꺼내어 화면에 보여주도록 했고. 이 부분은 잘 동작하고 있습니다.
public void run() {
// TODO Auto-generated method stub
Message msg = handler.obtainMessage();
if(jobcode == 1){ // 즐겨찾기 검색일 경우
bookmarklist = service.getBookmarklist(companyid, invoiceno, title);
msg.what = 1;
msg.obj = bookmarklist;
}else if(jobcode == 2){ // 검색 히스토리 검색일경우
}
// handler.sendMessage 함수를 바로 호출해버리면 이 스레드를 호출할때 같이 띄우는 ProgressDialog가 검색 버튼이 눌려지는 시점에 뜨지 않고
// 딜레이가 생기면서 늦게 떴다가 결과가 나온다. 그래서 이 부분을 디버깅해본 결과 handler.sendMessage 함수에서 발생하는 것이 확인이 되어
// 이 함수를 호출하기 전에 자체 딜레이를 주어 ProgressDialog가 먼저 뜨도록 유도를 한 뒤 handler.sendMessage 함수가 실행이 되도록 했다
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
handler.sendMessage(msg);
}
어쩌면 질문과는 무관한 코드를 보였을수도 있는데요..정리하자면 제 코드를 보시면 취소 버튼이 있는 ProgressDialog를 띄워주면서 데이터베이스를 조회하는 Thread가 실행이 됩니다. 그리고 화면에 조회결과를 뿌려준뒤 자동으로 ProgressDialog를 닫아줍니다. 근데 취소버튼을 클릭하면 클릭한 시점에서 취소버튼과 관련된 동작이 실행되지 않고 화면에 조회 결과를 다 뿌려준뒤에 취소버튼과 관련된 동작이 실행됩니다. 그건 제가 Log를 찍어봐서 확인했구요..즉 화면에 다 출력한뒤에 취소버튼이 동작한다는거죠..그 전에 취소버튼을 클릭했는데두요..ㅠㅠ..
Code Highlighter 를 써서 코드를 넣을려고 했는데 복사해서 붙여넣기로 하니까 Enter를 한 부분에 대한 처리를 하지 못해서 코드가 모두 한줄로 나오는 문제가 있어서 걍 맨 바닥에 코드를 붙여 넣었습니다. 양해 부탁드립니다..ㅠㅠ..
코드를 봐주시고 제가 무엇을 놓친것이 있는지 여러분들의 소중한 말씀 부탁드리겠습니다..
고맙습니다..