레트로핏 사용방법.


사용하는 방법은 대충 알겄는디 ??? 

정작 글로 쓸려고하니 뭔가 막히는 구문이 있다.



안드로이드에서 사용되는 여러 다양한 통신 기법 중 많이 사용되고 있는 레트로핏 통신방법


먼저 프로젝트를 생성한 다음 앱 그래들에 모듈을 포함시켜 준다.



GRADLE


//레트로핏 

implementation 'com.squareup.retrofit2:retrofit:2.4.0'

// 레트로핏 gson converter

implementation 'com.squareup.retrofit2:converter-gson:2.4.0'

// gson

implementation 'com.google.code.gson:gson:2.8.2'


//okhttp 로그 인터셉터

implementation 'com.squareup.okhttp3:logging-interceptor:3.10.0'


퍼미션에서 인터넷 권한을 준다.





//여기에 접속해서 필요한 데이터를 가져온다.

https://api.github.com/users/bearkinf



gson으로 데이터받을 클래스 생성.


/**유저 정보 관련 데이터 클래스*/

public class GithubUser {

    

    private String login;

    private String id;

    private String url;

    private String name;


    public String getLogin() {

        return login;

    }


    public void setLogin(String login) {

        this.login = login;

    }


    public String getId() {

        return id;

    }


    public void setId(String id) {

        this.id = id;

    }


    public String getUrl() {

        return url;

    }


    public void setUrl(String url) {

        this.url = url;

    }


    public String getName() {

        return name;

    }


    public void setName(String name) {

        this.name = name;

    }

}

/**저장소 관련 데이터 클래스.*/

public class GithubRepos {

    

    private String name;

    private String full_name;

    private String html_url;


    public String getName() { return name;  }


    public void setName(String name) {

        this.name = name;

    }


    public String getFull_name() {

        return full_name;

    }


    public void setFull_name(String full_name) {

        this.full_name = full_name;

    }


    public String getHtml_url() {

        return html_url;

    }


    public void setHtml_url(String html_url) {

        this.html_url = html_url;

    }

}




접속하기 위한 인터페이스를 만들고


public interface GithubConnectService {


    @GET("/users/{user}")

    Call<List<GithubUser>> getUser(@Path("user") String user);


    @GET("/users/{user}/repos")

    Call<List<GithubRepos>> getUserRepos(@Path("user") String user);

}



인터페이스르 사용하여 접속할 클래스 메서드를 만든다.


public class GithubConnectionApi {


    /**connection interface 리턴받음*/

    public static GithubConnectService setConnect() {


        OkHttpClient okHttpClient = new OkHttpClient.Builder()

                //통신시 request 및 response 상태 표시

                .addInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY))

                .build();


        return new Retrofit.Builder()

                .baseUrl("https://api.github.com/")

                // gson 데이터 파싱 메서드

                .addConverterFactory(GsonConverterFactory.create())

                // 통신 클라이언트 지정

                .client(okHttpClient)

                .build()

                // 통신 인터페이스 등록

                .create(GithubConnectService.class);

    }

}



MainActivity에서 통신 할 방법을 구현 한다.

public class MainActivity extends AppCompatActivity {


    Button button;

    TextView textview;


    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);


        textview = findViewById(R.id.textview);

        button = findViewById(R.id.button);



        button.setOnClickListener(new View.OnClickListener() {

            @Override

            public void onClick(View v) {


                Log.d("bear", "버튼 클릭");


                Call<GithubUser> githubUserCall = GithubConnectionApi.setConnect().getUser("bearkinf");


                githubUserCall.enqueue(new Callback<GithubUser>() {

                    @Override

                    public void onResponse(Call<GithubUser> call, Response<GithubUser> response) {


                        Log.w("bear", "response : " + response.body());


                        GithubUser user = response.body();

                        

                        Log.w("bear", "getId : " + user.getId());

                        Log.w("bear", "getLogin : " + user.getLogin());

                        Log.w("bear", "getName : " + user.getName());

                        Log.w("bear", "getUrl : " + user.getUrl());

                    }


                    @Override

                    public void onFailure(Call<GithubUser> call, Throwable t) {

                        t.printStackTrace();

                    }

                });

            }

        });

    }

}





안드로이드 4.4.4버전에서 ssl 관련 통신 에러 발생함.


'Android > study' 카테고리의 다른 글

MVP 패턴  (0) 2019.04.25
안드로이드 코틀린 프로젝트 디펜던시  (0) 2019.01.25
안드로이드 액티비티 및 프래그먼트.  (0) 2018.09.27
RxJava  (0) 2018.07.30


추상 클래스를 이용한 액티비티 구현 2-1.

2-2에서 퍼미션 권한 이용.



안드로이드 스튜디오 프로잭트 생성.


생성된 기본 액티비티.

MainActivity.java

//////////////////////////////////////////////////////////////////////////////////////////

public class MainActivity extends AppCompatActivity {


    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

    }

}

//////////////////////////////////////////////////////////////////////////////////////////



추상 클래스 BaseActivity 생성.

BaseActivity.java

//////////////////////////////////////////////////////////////////////////////////////////

abstract class BaseActivity extends AppCompatActivity {


    /**상속받은 곳에서 xml 레이아웃을 받아옴.*/

    abstract int setLayout();


    @Override

    protected void onCreate(@Nullable Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(setLayout());

    }


}

//////////////////////////////////////////////////////////////////////////////////////////


생성된 BaseActivity를 MainActivity에서 상속받음.

MainActivity.java

//////////////////////////////////////////////////////////////////////////////////////////

public class MainActivity extends BaseActivity {



    @Override

    int setLayout() {

        // BaseActivit에서 만들어 놓은 추상 메서그 구현.

        // setContentView(R.layout.activity_main);

        // 추상메서드로 구현.

        return R.layout.activity_main;

    }


    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        

    }

}


//////////////////////////////////////////////////////////////////////////////////////////



이렇게 작업 한 이유는 액티비티를 상속 받은 처리 중 퍼미션 사용시 필요한 클래스 들을 정의 하여 사용하기 위함.

구현이 필요 없을 시엔 기존에 사용하던 대로 사용 가능.



'Android > source code' 카테고리의 다른 글

안드로이드 추상 클래스 이용한 퍼미션 권한 설정. 2-2  (0) 2018.10.15
Android RecyclerView 예제  (0) 2018.10.15
동적 레이아웃 등록(xml)  (0) 2018.10.11
액티비티  (0) 2018.09.18
MVP 패턴 코틀린으로 작업  (0) 2018.08.14

MVP 패턴.





MODEL : 데이터 처리.


VIEW : 뷰 


PRESENT : MODEL과 VIEW 사이의 매개체



MVP 패턴의 동작


VIEW 에서 사용자 이벤트 수신

VIEW 에서 PRESENTER 이벤트 호출

PRESENTER 에서 MODEL 데이터 요청

MODEL 에서 PRESENTER 로 데이터 전달

PRESENTER 에서 전달받은 데이털 처리 후 VIEW 업데이트 요청

VIEW 에서 화면 업데이트



구현 방법


interface Contact


inner interface View

inner interface Present 


View 에서 처리할 이벤트 선언

Present 에서 처리할 이벤트 선언



View를 상속받는 Activiry 구현

Present를 상속받는 Presenter 구현


Presenter 에서 Model로 데이터 요청.(통신을 통한 서버 데이터 요청)


Model 에서 Presenter 가 요청한 데이터를 전달 후 Presenter에서 데이터 가공 후 View에 업데이트 요청


View 로 가공된 데이터를 가지고 화면 업데이트. 




MainActivityContract


MainActivity  MainActivityContract.View 상속


MainActivityPresenter MainActivityContract.Present 상속


MainActivityDataAction Present에서 데이터 요청




코틀린으로 코드 구현.




/**

 * 액티비티 상속 클래스

 */

abstract class BaseActivity : AppCompatActivity() {


    /**레이아웃 뷰 추상화 등록*/

    protected abstract val layoutId: Int


    override fun onCreate(savedInstanceState: Bundle?) {

        super.onCreate(savedInstanceState)

        setContentView(layoutId)

    }

}




/**

 * mvp 계약자 정의

 */

interface MainActivityContract {

    /**

     * 단순 화면 처리

     * 액티비이에서 뷰 구현

     */

    interface View {


        /** 뷰에 프레젠터 등록.*/

        val presenter: Present


        fun buttonClickChangeUI(count: Int)


    }


    /**

     * 프레젠터 뷰와 모델의 데이터 처리

     * 프레젠터 클래스를 생성하여 인터페이스 구현.

     */

    interface Present {


        /**

         * 프레젠터에 뷰 등록

         *

         */

        var view: View?


        /** 전달받을 뷰를 등록함.*/

        fun attachView(view: View)


        /** 뷰 해제*/

        fun detachView()



        fun buttonClickCountUp(count: Int)

    }

}


/**

 * MainActivity

 * 

 */

class MainActivity : BaseActivity(), MainActivityContract.View {


    /**BaseActivity에서 상속받은 변수. */

    override val layoutId = R.layout.activity_main

    /**뷰에 지정한 프레젠터 등록.*/

    override val presenter: MainActivityContract.Present = MainActivityPresenter()


    override fun onCreate(savedInstanceState: Bundle?) {


        super.onCreate(savedInstanceState)

        presenter.attachView(this)

        buttonEvent()

    }



    fun buttonEvent() {


        button_Click.setOnClickListener(View.OnClickListener {

            Log.w("bear", "buttonclick")

            presenter.buttonClickCountUp(count)

        }

        )

    }


    var count = 0

    override fun buttonClickChangeUI(count: Int) {

        this.count = count

        textview.text = "${this.count}"

    }

}




/**

 * 데이터를 처리하는 프레젠터

 * 처리된 결과를 등록한 뷰에 전달.

 */

class MainActivityPresenter : MainActivityContract.Present {


    /**뷰 초기화*/

    override var view: MainActivityContract.View? = null


    /**뷰 지정.onCreate 에 등록*/

    override fun attachView(view: MainActivityContract.View) {

        this.view = view

    }


    /**뷰 해제*/

    override fun detachView() {

        this.view = null

    }


    override fun buttonClickCountUp(count: Int) {

        view?.buttonClickChangeUI(count + 1)

    }

}






이런식으로 사용이 가능하다.





RxJava



함수형 프로그래밍, 비동기 작업, 서버연동, 옵저버 패턴, 마블 다이어그램.

학습 곡선이 높다고 표현한다. 어떤식으로 작업을 해야 쉽게 이해가 될 수 있을까?



기본 


Observable : 데이터 생성을 위한 시작 클래스. 정적 팩토리함수로 인스턴스를 생성. 


just       : 데이터를 발행하는 정적팩토리 함수. 

     데이터를 발행하려는 메서드.하나의 인자 또는 최대 10개 까지의 같은 타입의 인자를 받음.

             subscribe()를 호출해야 실제 데이터 발행이 진행됨.


subscribe  : 데이터를 구독하는 함수. Observable에 데이터를 발행하라고 요구 (이함수가 없으면 RxJava 가 실해되지 않는다.)



Observable의 팩토리 함수 


create(), just(), from(), 

fromArray(), fromIterable(), fromCallable(), fromFuture(),

interval(), range(), timer(), defer()




Single : 오직 1개의 데이터만 발행하도록 한정됨.

  보통 결과가 유일한 서버api를 호출할때 사용.

  배열 및 리스트로 값을 받아도 1번의 값만 동작.



Flowable : 뜨거운 Observable 에서 데이터를 처리할때 배압을 고려할때 사용.

           배압은 Observable에서 테이타를 발행하는 속도와 구독자의 처리하는 속도의 차이가 발생할때 사용.

   Observable과 같은 방법으로 사용 하여도 된다.




기본 예제


   //자바 8 메서드 레퍼런스활용

   Observable.just("start Rxjava", "Rxjava end").subscribe(System.out::println);


   //람다식 적용.

   Observable.just("start Rxjava", "Rxjava end").subscribe(

           s -> {

               System.out.println("실행결과 : " + s);

       }

   );


   // 람다식 적용안함.

   Observable.just("start Rxjava", "Rxjava end").subscribe(new Consumer<String>() {

       @Override

       public void accept(String s) throws Exception {


           System.out.println("실행결과 : " + s);


       }

   });


   Single.just("fsdjaklfjasdklf").subscribe(System.out::println);


   Flowable.just("start Rxjava", "Rxjava end").subscribe(System.out::println);




연산자 활용


interval() : 일정시간 간격으로 데이터 흐름을 생성.

     주어진 시간을 간격으로 0부터 1씩 증가하는 Long 객체를 발행.



















'Android > study' 카테고리의 다른 글

MVP 패턴  (0) 2019.04.25
안드로이드 코틀린 프로젝트 디펜던시  (0) 2019.01.25
안드로이드 액티비티 및 프래그먼트.  (0) 2018.09.27
레트로핏, okhttp  (0) 2018.08.27

+ Recent posts