본문 바로가기

Android

Retrofit2 + Okhttp3

 

Retrofit2

Retrofit은 Square사에서 만든 라이브러리로 서버와 통신하기 위한 방법 중 하나입니다. 구현이 간단하며 응답속도가 빠른것이 장점입니다. 아래 사진을 보면 Retrofit이 가장 빠른것을 볼 수 있습니다.

 

 

Okhttp3

Retrofit은 기본적으로 Okhttp를 네트워킹 계층으로 활용하며 그 위에 구축됩니다. OkHttp는 이미 Retrofit2 모듈의 종속성에 포함되어 있어, 별도의 OkHttp 설정이 필요하다면 Retrofit2에서 OkHttp 종속성을 제외해야 합니다.


사용법

 

mysql과 php를 이용하여 서버 구축을 해주었습니다. 저는 로그인 서버를 구축하기위해 user테이블을 만들어주었습니다.

CREATE TABLE `USER`  (
  `userID` VARCHAR(20) NOT NULL,
  `userPassword` VARCHAR(20) not NULL,
 `userName` VARCHAR(20) not NULL,
  PRIMARY KEY (`userID`))
    default character set utf8 collate utf8_general_ci
ENGINE = InnoDB;

 

 

서버에 userID와 userPassword를 보내 회원이 있는지 확인한다음 성공하면 true와 userName을 가져오고 실패하면 false를 가져오게하였습니다.

 

LoginApi.php

require_once dirname(__FILE__) . '/LoginFileHandler.php';
 
$response = array();
 
if (isset($_GET['apicall'])) {
    switch ($_GET['apicall']) {
       
        case 'get':
 
            if(isset($_POST['userID']) && strlen($_POST['userID']) > 0 && isset($_POST['userPassword']) && strlen($_POST['userPassword']) > 0){
                

                $userID = $_POST['userID'];
                $userPassword = $_POST["userPassword"];

                $upload = new LoginFileHandler();
                $response['success'] = $upload->get($userID,$userPassword,0); //성공여부 반환
                $response['userName'] = $upload->get($userID,$userPassword,1); //username 반환
 
                
                break;
            }

    }
}
 
echo json_encode($response);
 

 

LoginFileHandler.php

class LoginFileHandler
{
 
    private $con;
 
    public function __construct()
    {
        require_once dirname(__FILE__) . '/DbConnect.php'; //db연결
 
        $db = new DbConnect();
        $this->con = $db->connect();
    }
 
 
    public function get($userID, $userPassword,int $i)
    {
        $stmt = $this->con->prepare("SELECT * FROM USER WHERE userID = ? AND userPassword = ?");
        $stmt->bind_param("ss", $userID,$userPassword); //아이디와 패스워드를 넣어 유저 정보를 가져옵니다
        $stmt->execute();
        $stmt->bind_result($userID, $userPassword, $userName);
 
        
      
        if( $i == 0 ) {

            $temp = false;

            while($stmt->fetch()) {
              $temp = true;
            }
           
        }else{

            while($stmt->fetch()) {
    
                $temp = $userName;

            }
        } //0이면 success를 반환하게하고 1이면 username을 반환하게 하였습니다

  

        return $temp;
    }
 
}

 

데이터를 넣으면 원하는 정보를 가져오는것을 확인할 수 있습니다.


서버 구축이 끝났으니 안드로이드 스튜디오에서 데이터를 전송해주는 코드를 만들어줍니다.

 

 

AndroidManifest와 build.gradle에 아래와 같은 코드를 추가해줍니다.

<uses-permission android:name="android.permission.INTERNET" />
    implementation 'com.squareup.retrofit2:retrofit:2.6.0' // Retrofit2 2.6.0
    implementation 'com.squareup.retrofit2:converter-gson:2.6.2'   // Json Parser
    implementation 'com.squareup.okhttp3:okhttp:3.11.0'//okhttp3
    implementation 'com.squareup.okhttp3:logging-interceptor:3.11.0'//okhttp3

 

 

 

APIClient를 만들어줍니다.

public class APIClient {

    private static Retrofit retrofit = null;

    public static Retrofit getClient() {
        HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
        interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);

        OkHttpClient client = new OkHttpClient.Builder().addInterceptor(interceptor).build();

        retrofit = new Retrofit.Builder()
                .baseUrl(서버url)
                .addConverterFactory(GsonConverterFactory.create())
                .client(client)
                .build();

        return retrofit;
    }


}

 

 

 

데이터를 받기위한 class도 생성해줍니다.

http://www.jsonschema2pojo.org/ 여기에서 쉽게 만들 수 있습니다.

public class LoginResponseInfo {

    @SerializedName("success")
    @Expose
    private Boolean success;

    @SerializedName("userName")
    @Expose
    private String userName;

    public Boolean getSuccess() {
        return success;
    }

    public void setSuccess(Boolean success) {
        this.success = success;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

}

 

 

 

Api interface도 만들어줍니다. 나중에 여기에 적은 LoginPut함수를 이용하여 서버에 데이터를 전달해줍니다.

public interface Api {


    @Multipart
    @POST("LoginApi.php?apicall=get")
    Call<LoginResponseInfo> LoginPut(@Part("userID") RequestBody userID, @Part("userPassword") RequestBody userPassword); //로그인 데이터 검색

}

 

 

 

login을 하기위한 코드를 작성해줍니다.

 private void login(final String userID, final String userPass) {

        RequestBody userIDBody = RequestBody.create(MediaType.parse("text/plain"), userID);
        RequestBody userPassBody = RequestBody.create(MediaType.parse("text/plain"), userPass);

        Api Api = APIClient.getClient().create(Api.class);
        Call<LoginResponseInfo> call = Api.LoginPut(userIDBody, userPassBody);

        call.enqueue(new Callback<LoginResponseInfo>() {
            @Override
            public void onResponse(Call<LoginResponseInfo> call, Response<LoginResponseInfo> response) { //통신 성공

                if (response.isSuccessful()) {

                    LoginResponseInfo loginResponseInfo = response.body();

                    if (loginResponseInfo.getSuccess()) { // 만약 success가 true이면

                        InputNameData(loginResponseInfo.getUserName()); // SharedPreferences 이용해 name을 저장해줍니다.

                        AlertDialog.Builder builder = new AlertDialog.Builder(LoginActivity.this);
                        builder.setMessage("자동로그인에 등록하시겠습니까?");
                        builder.setPositiveButton("예",
                                new DialogInterface.OnClickListener() {
                                    public void onClick(DialogInterface dialog, int which) {
                                        InputLogData(userID, userPass, true); // 예를 누르면 true를 넘겨주어 SharedPreferences에 아이디와 패스워드를 저장시켜주었습니다.
                                        Intent intent = new Intent(LoginActivity.this, MainActivity.class);
                                        startActivity(intent);
                                    } 
                                }); 
                        builder.setNegativeButton("아니오",
                                new DialogInterface.OnClickListener() {
                                    public void onClick(DialogInterface dialog, int which) {
                                        InputLogData(userID, userPass, false); //아니오를 클릭하면 false를 넘겨주어 저장되지 않도록 만들어주었습니다.
                                        Intent intent = new Intent(LoginActivity.this, MainActivity.class);
                                        startActivity(intent);
                                    }
                                });
                        builder.show();

                    } else {
                        Toast.makeText(getApplicationContext(), "로그인 실패", Toast.LENGTH_SHORT).show();
                    }


                } else { //response 실패

                }

            }

            @Override
            public void onFailure(Call<LoginResponseInfo> call, Throwable t) { //통신 실패
                Toast.makeText(getApplicationContext(), t.getMessage(), Toast.LENGTH_SHORT).show();
            }
        });
    } // retrofit 데이터 받아오기

 

 

 

참고

https://square.github.io/retrofit/

https://square.github.io/okhttp/interceptors/

https://jongmin92.github.io/2018/01/29/Programming/android-retrofit2-okhttp3/

https://www.simplifiedcoding.net/retrofit-upload-file-tutorial/#Handling-API-Calls

'Android' 카테고리의 다른 글

FloatingActionButton 구현  (0) 2021.03.13
당겨서 새로고침 기능 추가하기  (0) 2021.01.23
Activity 생명주기  (0) 2021.01.21
안드로이드 4대 컴포넌트  (0) 2021.01.20
Toolbar 검색버튼 만들기  (0) 2021.01.15