제가 보는 관점에서 코드를 역할에 맞게 클래스별로 쪼개서 정리해 봤습니다. 완벽한 코드는 아니니 이런 식으로 만들 수 있다는 가이드로 여기시면 좋을 것 같습니다.
눈여겨 보실 것은 LoginActivity 와 LoginTask는 LoginTask.Listener 인터페이스를 통해서 데이터를 주고 받도록 변경하였습니다. 이렇게 함으로써 두 클래스사이의 종속성이 줄어들고 LoginTask는 좀 더 재사용이 쉬워지게 됩니다.
public class UiError {
private final String title;
private final String message;
public UiError(title: String, message: String) {
this.title = title;
this.message = message;
}
public String getTitle() { return title; }
public String getMessage() { return message; }
}
public class LoginActivity extends AppCompatActivity implements LoginTask.Listener {
private EditText emailEdit;
private EditText pwdEdit;
private String getEmail() { return emailEdit.getText().toString().trim(); }
private String getPassword() { return pwdEdit.getText().toString().trim(); }
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
emailEdit = findViewById(R.id.email);
pwdEdit = findViewById(R.id.pw);
Button login = findViewById(R.id.login);
login.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
login();
}
);
Button register = findViewById(R.id.register1);
register.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(login.this, RegisterActivity.class);
startActivity(intent);
}
});
}
private void login() {
UiError uiError = validateLoginInput();
if (uiError != null) {
showUiError(uiError);
return;
}
peformLoginRequest();
}
@Nullable
private UiError validateLoginInput() {
if ("".equals(getEmail()) || "".equals(getPassword())) {
return UiError("알림창", "데이터를 입력해주세요");
}
return null;
}
private void showUiError(UiError uiError) {
showError(uiError.getTitle(), uiError.getMessage);
}
private void showError(String title, String message) [
AlertDialog.Builder builder = new AlertDialog.Builder(this);
AlertDialog alertDialog = builder.setTitle(title)
.setMessage(message);
.setPositiveButton("확인")
.create();
alertDialog.show();
}
private void peformLoginRequest() {
LoginTask task = new LoginTask(this);
task.setLoginInput(getEmail(), getPassword());
task.execute();
}
@Overrid
public void loginFailureWithError(LoginError error) {
switch (error) {
case HTTP_ERROR:
showError("로그인 실패", "메세지");
break;
case INVALID_USER:
showError("로그인 실패", "메세지");
break;
case JSON_PARSE_ERROR:
showError("로그인 실패", "메세지");
break;
case MISC_ERROR:
showError("로그인 실패", "메세지");
break;
}
}
@Overrid
public loginSucceeded(List<Memeber> members){
Intent intent = new Intent(login.this, first.class);
startActivity(intent);
}
}
LoginTask입니다. 사용자에게 로그인 에러메세지를 보여줄 때 아이디가 틀렸는지, 패스워드가 잘못되었는지 구체적으로 알려주시는 것은 보안을 허술하게 만들 수 있습니다. 일반적인 메세지만 보여주어야 합니다.
public enum LoginError {
HTTP_ERROR, INVALID_USER, JSON_PARSE_ERROR, MISC_ERROR
}
public class LoginResult {
@Nullable private final LoginError error;
private final List<Memeber> members;
private LoginResult(@Nullable LoginError error, List<Member> members) {
this.error = error;
this.members = members;
}
public static LoginResult error(LoginError error) {
return new LoginResult(error, new ArrayList<>());
}
public static LoginResult success(List<Member> members) {
return new LoginResult(null, members);
}
public boolean isError() {
return error != null;
}
}
public class Memeber {
private final String email;
private final String name;
// 생성자, getters & setters생략
}
public class loginTask extends AsyncTask<Void, Void, LoginResult> {
private static final String LOGIN_ENDPOINT = "http://서버ip/LoginDB.php";
interface Listener {
void loginFailureWithError(LoginError error);
void loginSucceeded(List<Memeber> members);
}
private String email, password;
private Listener lisetner;
public loginTask(@NotNull Listener lisetner) {
this.listener = listener;
}
public void setLoginInput(String email, String password) {
this.email = email;
this.password = password;
}
@Override
protected String doInBackground(String... params) {
try {
String responseString = HttpRequestUtil.post(LOGIN_ENDPOINT, getPostParameters());
if ("error".equals(responseString) || "pwerr".equals(responseString)) {
return LoginResult.error(LoginErrorType.INVALID_USER);
}
return parseJSON(responseString);
} catch (IOException e) {
return LoginResult.error(LoginErrorType.HTTP_ERROR);
} catch (JSONException e) {
return LoginResult.error(LoginErrorType.JSON_PARSE_ERROR);
} catch (Exception e) {
return LoginResult.error(LoginErrorType.MISC_ERROR);
}
}
private String getPostParameters() {
return "m_email" + email + "$m_pw=" + password;
}
private LoginResult parseJSON(String json) {
List<Member> members = new ArrayList<>();
JSONObject jsonObject = new JSONObject(callBackValue);
JSONArray jsonArray = jsonObject.getJSONArray("member");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject item = jsonArray.getJSONObject(i);
checkid = item.getString("m_email");
checkpwd = item.getString("m_pw");
String name = item.getString("m_name");
members.add(new Member(checkid, name));
}
return LoginResult.success(members);
}
@Override
protected void onPostExecute (LoginResult loginResult) {
if (loginResult.isError()) {
listener.loginFailureWithError(loginResult.getError());
return;
}
listener.loginSucceeded(loginResult.getMembers());
}
}
public class HttpRequestUtil {
public static String post(String urlString, String postParameters) {
URL url = new URL(urlString);
// 생략
return bufferedReader.close();
}
}
HttpRequest를 하는 부분은 Readability를 위하여 별도의 유틸클래스로 분리했습니다. 일단 http 핸들링에 익숙해지시면 Retrofit같은 라이브러리를 사용하셔서 보일러플레이트 코드를 줄이시기 바랍니다.