안드로이드/항상 하는 것

1. Rxandroid와 Rxjava2 라이브러리를  gradle:모듈수준에서 추가해준다.

implementation 'io.reactivex.rxjava2:rxandroid:2.0.2'
implementation 'io.reactivex.rxjava2:rxjava:2.x.x'

   implementation 'com.jakewharton.rxbinding2:rxbinding:2.1.1'

 +Rxview.clicks를 사용하기 위한 Rxbinding 라이브러리 추가! ( 버튼,텍스트뷰 변수 / 클릭리스너 생성없이도 버튼->텍스트뷰 연결!)


implementation 'com.trello.rxlifecycle2:rxlifecycle-android:2.2.1'
implementation 'com.trello.rxlifecycle2:rxlifecycle-components:2.2.1'

 + .compost bindToLifeCycle을 사용하기 위한 Rxlifecycle 라이브러리 추가 ( 3.1.0 버전부터는 complie 대신 implementation으로 다 바뀜)
*** rx바인딩 사용시 activity는 RxAppcompatAcitivity 상속해줘야함


정리)

implementation 'io.reactivex.rxjava2:rxandroid:2.0.2'
implementation 'io.reactivex.rxjava2:rxjava:2.x.x'
implementation 'com.jakewharton.rxbinding2:rxbinding:2.1.1'
implementation 'com.trello.rxlifecycle2:rxlifecycle-android:2.2.1'
implementation 'com.trello.rxlifecycle2:rxlifecycle-components:2.2.1'
public class MainActivity extends RxAppCompatActivity {


버튼을 binding시켜서, 함수실행 +  토스트 띄우는 예제코드

RxView.clicks(findViewById(R.id.btn_publish))
.subscribe( e-> {
doPublish(); //함수 실행
Toast.makeText(this, "PublishSubject", Toast.LENGTH_SHORT).show(); //해당 토스트 띄우기
});


2. Letrolambda식(java8)을 사용하기 위해서는, 마찬가지로 gradle:모듈수준에서 android{} 안에 compileOptions{}만 주면 된다.

buildTypes{} 와 같은 수준에서 바로 그위에 넣어주면 됨

compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}



Stetho 라이브러리는 facebook에서 개발된 안드로이드 디버깅 툴이다.


1. Stetho라이브러리를 추가하자.(http://facebook.github.io/stetho/)


compile 'com.facebook.stetho:stetho:1.4.2' // 네트워크 호출 인터셉트 후 디버깅 하고 싶다면 network helper 도 추가
compile 'com.facebook.stetho:stetho-okhttp3:1.4.2'

- 이때, 네트워크 분석을 위해서 Stetho-okhttp3 라이브러리도 같이 추가한다.

  비록 내가 만든 앱은 Retrofit2로 통신을 하지만 아래의 구조를 가지기 때문에 stetho-okhttp3이다.

  

  

2. 기존 프로젝트의 어느 액티비티든 적용시키는 [Application]클래스를 만들자.


(1) Application을 상속하는 MyApplication 클래스를 생성한 뒤에, 아래코드를 넣으면  [크롬 Inspect 툴]에서 디버깅이 가능하다.


public class MyApplication extends Application{
@Override
public void onCreate() {
super.onCreate();
if (BuildConfig.DEBUG) Stetho.initializeWithDefaults(this); // Debug 모드일때만 Stetho init
OkHttpClient stethoInterceptingClient = new OkHttpClient.Builder()
.addNetworkInterceptor(new StethoInterceptor()) // Stetho Interceptor 추가해야 Chrome Inspect tool 에서 확인 가능, 필수 아님
.build();

Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.client(stethoInterceptingClient) // Retrofit build 할때 client를 새로 interceptor가 추가 되어있는 client로 교체한다
.build();
}
}

 - if()문은, 디버깅모드일 때만 Stetho를 사용하도록 하는 코드다.

 - 밑에 okHttpClient는 네트워크분석을 위해 Stetho <--> 통신 간에 다리를 놔주는 Interceptor다.

 - 밑에  Retrofit관련코드는 빌더를 만들 때, stethoInterceptor를 retrofit의 client로 연결해주는 코드다.


*내 프로젝트는 특별히 어댑터에서 Retrofit의 baseUrl을 받아야만 해서, 객체 생성 및 빌더를 어댑터클래스에서 선언했었다. 

 그래서 아래처럼 코드를 구성해야했다.


MyApplication.java

public class MyApplication extends Application{
public static OkHttpClient stethoInterceptingClient;
@Override
public void onCreate() {
super.onCreate();

if (BuildConfig.DEBUG) Stetho.initializeWithDefaults(this); // Debug 모드일때만 Stetho init
stethoInterceptingClient = new OkHttpClient.Builder()
.addNetworkInterceptor(new StethoInterceptor()) // Stetho Interceptor 추가해야 Chrome Inspect tool 에서 확인 가능, 필수 아님
.build();

}
}

RecyclerViewAdapter.java

Retrofit retrofit2 = new Retrofit.Builder()
.baseUrl( object.Image+ "/")
.addConverterFactory(GsonConverterFactory.create())
.client(stethoInterceptingClient) // Retrofit build 할때 client를 새로 interceptor가 추가 되어있는 client로 교체한다
.build();

 - MyApplication클래스는 public static 만 붙히면, 전 영역의 Activity에서 다 사용이 가능하다.***

   [ public static 전역변수 --> MyApplication.전역변수 in 어느 액티비티 ] 

   [ public static 매쏘드() --> MyApplication MyApp = (MyApplication)getApplicationContext();  -->   MyApp.매쏘드(); ]

   [ 그래서 토스트메세지 or 폰트 적용 or 로딩 다이얼로그 구현할 때, 이 Application클래스에 선언한다 ]

   참고 : http://uroa.tistory.com/43(어플리케이션 클래스 설명),  http://gun0912.tistory.com/72 (로딩중띄우기), http://gun0912.tistory.com/10 (폰트적용)


   그러므로 다른 클래스에서 선언되는 Retrofit 객체에 들어갈 OkhttpClient는 전역변수로 public static으로 선언했다.


3. 매니페스트에  MyApplication클래스를 <application>으로 등록하자. 

 - 핵심은 android:name = " .어플리케이션 클래스명 " 이다.


<application
android:name=".MyApplication"

android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:largeHeap="true"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">


4. 크롬에서 [chrome://inspect/ ]를 쳐서 Stetho를 이용해보자.


(1) 검색된 device 정보 아래 [inspect]를 눌러 들어갈 수 있다.





(2) 파싱되는 정보가 나온다. 더이상 json파싱을 로그로 확인하지 않아도 된다.



(3) Database(sqlite)는 조회만 된다.(쿼리문을 날리면 수정이 가능하다)





(4) SharedPreferences 는 value값을 마음대로 수정 가능하다.

배포버전에서는 로그캣을 안찍으면서

개발버전(디버그버전)에서만 [ 호출위치 ]와 [ 개인Tag]와 함께 로그가 찍히도록

커스텀 로그캣(Custom Logcat)을 만들어보자.



[1]

 

1. 먼저 build.gradle(Module:app)에 아래 코드를 추가합니다.


buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'

debuggable false
buildConfigField "boolean", "DEBUG_MODE", "false"

}
debug{
debuggable false
buildConfigField "boolean", "DEBUG_MODE", "true"

}
}

 - release {}는 배포버전이 행동이고, debug{}는 개발모드일 때의 행동입니다.

 - 프로젝트 생성시 항상 나타는 minifyEnabled proguard의 사용여부로서, 앱이 배포하기전까지는 false로 둔다.

 - debuggableLog가 찍히는지 유무와는 관계없다. 에뮬레이터 작동시 로그캣에 로그는 찍히나 프로젝트만 단독 필터를 못하게 된다.

  (*지니모션에서는 필터됨;;)




 - 우리는 debug{}개발모드에서도 프로젝트 단독으로 필터 안되도록 false로 둔다.

 - buildConfigFielddebug{}개발모드에서만 boolean상수 DEBUG_MODE에 true가 되도록 합니다. 

   이것은 커스텀으로 로그를 찍어주는 Logger클래스에서 배포버전{} false / 디버그버전{} true로 개발용에서만 로그가 찍히도록 조건문에 쓰이게 된다.


2. Logger.java 클래스를 만들어주기

public class Logger {
static final String TAG = "nittaku";



public static void v(String msg){
if(BuildConfig.DEBUG_MODE){
Log.v(TAG, buildLogMsg(msg));
}
}

public static void d( String msg){
if(BuildConfig.DEBUG_MODE){
Log.d(TAG, buildLogMsg(msg));
}
}

public static void i( String msg){
if(BuildConfig.DEBUG_MODE){
Log.i(TAG, buildLogMsg(msg));
}
}

public static void w( String msg){
if(BuildConfig.DEBUG_MODE){
Log.w(TAG, buildLogMsg(msg));
}
}

public static void e( String msg){
if(BuildConfig.DEBUG_MODE){
Log.e(TAG, buildLogMsg(msg));
}
}

public static String buildLogMsg(String message) {
StackTraceElement ste = Thread.currentThread().getStackTrace()[4];
StringBuilder sb = new StringBuilder();
sb.append("[");
sb.append(ste.getFileName().replace(".java", "")); sb.append("::");
sb.append(ste.getMethodName()); sb.append("]");
sb.append(message);
return sb.toString();
}




}

- 이 클래스를 추가해주면, 로그를 찍을 때, Logger.d(" 로그내용 ")만 호출하면 된다.

DEBUG_MODE를 사용하므로 디버그모드일 때만 로그가 찍히게 된다.

- TAG는 내가 미리 지정해 놓으므로, 로그캣에서 필요할 때 tag명으로 필터링 할 수 있다.

- buildLogMsg()에서는 호출되는 경로를 알려주게 된다. 



(1) 폴더복사(폴더명복사해서 약간 수정하기) -> 

(2) 안스에서 new->import projects->

(3) setting.gradle에서 스페이스로 sync now -> 

(4) crtl+alt+shift+s >flavor> id정보 수정하기 ->

(5)자바패키지명바꾸기->

(6)build->rebuild project

(7) strings.xml에서 앱명바꾸기 

(8) MySQLiteHelper.java에서 db version 1로 초기화하기

   (앱이름 바꿔서 새로깔리니까)

+ Recent posts