음.. 로그인과 로그인 확인을 위한 기능을 구현중인데요..
로그인 하는 부분이 여러번 나올것 같아 static 클래스로 만든 Login 클래스 내부에 메서드로 만들어 두려고 합니다..
그런데 로그인과 같은 경이 웹과 연동하는 경우 쓰레드를 써야되잖아요..
전 메서드에 파라미터로 아이디와 패스워드를 넘기면 로그인 확인에 대한 세션값을 리턴하는 형태로 만들려고 하거든요..
그런데 이걸 하려다 보니 대충 이런 형태가 되는데요..
public String login(String id, String pw){
String sessionID = "";
new Thread(){
public void run(){
sessionID = requestToServer("URL주소", id, pw);
}
}.start();
return sessionID;
}
그니까 메서드 내부에서 쓰레드를 쓰게 되는데.. 이게 좀 아닌거 같아서요..
일단 첫번째 문제는 sessionID 값을 받아오는게 쓰레드 내부여서 sessionID를 지금처럼 메서드 내부에 선언하지 못하고
클래스 전역변수로 선언해야 된다는 문제가 있구요..
값을 리턴하는것도 쓰레드 작동이 끝나고 리턴이 되야 되는데 그게 안된다는 문제도 있군요..
일반적으로 메서드 내부에 쓰레드를 두는방식을 사용하지 않나요??
보통 이런 페턴을 많이 쓰죠.
interface LoginCallback
{
void onLoginComplete(boolean success, String session_id, String fail_reason);
}
public void loginAsync(final String id, final String pw, final LoginCallback callback)
{
new Thread(){
public void run(){
String sessionID = requestToServer("URL주소", id, pw);
callback.onLoginComplete(session_id != null, session_id, "Suceess");
}
}.start();
}
loginAsync()를 부른 후에 로그인이 완료되면 Callback을 부르는 구죠입니다.
login하는 동안 로그인 중이라는 메시지 보여주실껀가요?
그럼 loginAsync()부르기 전에 progress dialog보여주고 onLoginComplete()에서 progress dialog hide시키면 되겠네요.
음 그럼 onLoginComplete()가 main thread에서 실행되어야 하는군요.
이런걸 편하게 해 주기 위해 AsyncTask가 있죠. 다음처럼 쓰시면 됩니다.
public void loginAsync(final String id, final String pw)
{
new AsyncTask<Void, Void, String>() {
private ProgressDialog mProgressDlg;
public void onPreExecute() {
mProgressDlg = new ProgressDialog("로그인중..."...);
}
public void doInBackground(Void... params) {
return requestToServer("http://xxxxx/login.php?id=" + id + "&pw=" + pw);
}
public void onPostExecute(String session_id)
{
mProgressDlg.dismiss();
// 이 시점이 로그인 완료된 상태입니다. 에러라면 에러 메시지 보여주고 아니면 다음 화면으로 넘어가면 됩니다.
}
}.execute();
}
이런건 어떤가요..
public class LoginThread extends Thread implements commonValue{
final String URL ="세션값을 리턴하는 로그인 주소";
Handler handler;
ArrayList<String> param;
public LoginThread(Handler handler, String id, String pw){
this.handler = handler;
param = new ArrayList<String>();
param.add("id=" + id);
param.add("&password=" + pw);
}
public void run(){
String sessionID = Util.requestToServerForResult(URL, param);
Message msg = handler.obtainMessage();
if(sessionID == null){
msg.arg1 = LOGIN_FAULE;
}
else{
msg.arg1 = LOGIN_SUCCESS;
msg.obj = sessionID;
}
handler.sendMessage(msg);
}
}
로그인쓰레드를 만들고 쓰레드 생성시 Handler를 전달 받습니다. 그리고 로그인을 수행하는 각 페이지에서는 각자 핸들러를 만든후에 쓰레드 실행시킬때 핸들러 인자를 전달하는 방식요..
책대로 배운 내용이었으니 좀 베이직한 방식이 아닌가 합니다만..
콜백을 부르는 구조와 어떤 차이가 있는지요??
Handler 에 대해서 알아보시고 session 정보는 Preference 저장으로 해보세요
보통은...빈번하게 쓰이는 정도라면 당연히 Thread 나 Runnable 을 상속받은 클래스에서 별도로 처리해야겠죠.