지난 포스팅에서 ContentProvider의 개념, 사용법과 ContentProvider에서 사용하는 UriMatcher에 대해 기술하였다.
아직 포스팅을 접하지 못한 분은 아래 링크 클릭.
[Android] ContentProvider 누구보다 쉽게!
[Android] UriMatcher, 스마트하게 써보자!
ContentProvider에대해 기술한 포스팅에서 필자는 기존의 안드로이드 데이터베이스의 데이터 공유 방식이 아닌 메서드 콜을 통한 Bundle 반환 방식의 ContentProvider 샘플 코드를 기술하였다.
본 포스팅에서는 해당 방식에 대해 좀 더 자세하게 다루어보고자 한다.
메서드 콜 방식?
ContentProvider의 기본 방식은 이전 포스팅에서 언급하고, 아래 그림과 같이 CRUD에 해당하는 API를 ContentResolver를 통해 호출하는 방식을 취하며, 결과데이터는 Cursor, Uri, Int와 같이 다양한 데이터 타입으로 반환하는 구조였다.
하지만 본 포스팅에서는 기존의 방식이 아닌 좀 더 유연하게 외부 연동에 대응하며, 불필요한 데이터베이스 사용을 지양하기 위해 아래와 같이 메서드 콜 방식의 Bundle 객체를 제공해주는 방식으로 ContentProvider를 사용해보고자 한다.
ContentProvider의 API 중 call API의 경우 상세 스팩은 아래와 같다.
스펙 상에서는 ContentProvider를 호출하는 authority 정보와 method 명을 바탕으로 호출하면, Bundle 객체를 반환한다고 명시되어 있다.
하지만 필자는 외부 연동과정에 있어 method 명을 제공하는 것 보다는 외부 연동 키를 제공해주고, 외부에서 접근하는 키에 따른 Bundle 객체를 제공해주는 방식을 취하고자 한다.
그래서 어떻게 해야하죠?
해당 내용은 지난 포스팅에서 샘플로 작성했던 코드를 참조하며 아래코드를 보면 된다.
/**
* 제공하는 데이터의 MIME 타입을 조사하는 메서드.
* 정보의 개수에 따라 MIME 타입의 형식이 다름.
* 강제 규칙은 아니지만 대체로 다음 형식에 작성
*
* 단수 : vnd.회사명.curosr.item/타입
* 복수 : vnd.회사명.cursor.dir/타입
*/
override fun getType(uri: Uri?): String? {
val uriMatcher = RozeUriMatcher()
return uri?.let {
uriMatcher.getExternalCallInfo(uri)
} ?: return null
}
외부 앱에서는 ContentProvider의 getType을 통해 반환되는 메서드 키 값을 바탕으로 call 메서드에 입력만 해줌으로써 별도의 키 값을 하드코딩하지 않고 연동하여 데이터를 받아 올 수 있다.
/**
* 외부에서 메서드 호출 접근 시 처리한다.
*/
override fun call(method: String?, arg: String?, extras: Bundle?): Bundle {
return when (method) {
DabalExternal.SAMPLE.dabalExternalMethodKey -> isDabal()
else -> Bundle()
}
}
Bundle을 통해 데이터를 넘겨주기 때문에, 앱 연동시에 좀 더 유연하게 데이터를 넘겨줄 수 있다. 또한, 외부 앱 연동 개발자는 제공받은 Bundle 객체에서 필요한 데이터만 발췌하여 사용하면 되기 때문에 Cursor 객체에서 불필요한 코드를 통해 데이터를 확인하며 추출하는 일련의 작업을 생략할 수 있다.
/**
* ContentResolver를 통해 외부 앱에서 데이터 추출 샘플
*/
private fun getData() {
val testUri:Uri = Uri.parse("content://com.dabal.external/dabal_test_call")
val method = this.contentResolver.getType(testUri)
val bundle:Bundle? = this.contentResolver.call(testUri, method,null, null)
val resultData: String? = bundle?.getString("result")
resultString?.text = resultData
}
위의 방식으로 구현하게 되면, 외부 연동 개발자 입장에서는 호출 할 Uri 정보, Bundle로 넘겨받는 데이터 스펙에 대해서만 알고있다면, 내부에서 수정하는 키정보에 따른 영향도를 줄일 수 있다.
지금 하나의 케이스에 대해서만 기술했을 땐, 크게 와 닿지 않을 수 있다. 하지만 연동되는 외부 앱 정보가 많아지면서 리팩토링이 필요해지고 경우에 따라서 사전에 정의한 메서드 명, 키 정보등 ContentProvider 내부의 정보가 바껴야하는 상황에서는 위의 방식으로 구현하지 않으면 수정이 어렵게되어 스파게티 코드를 양산할 가능성이 높게된다.
마치며
본 포스팅에서는 ContentProvider를 call API를 이용해 사용하는 방법에 대해 기술하였다.
필자처럼 안드로이드 내부 데이터베이스를 사용하지 않고 외부 연동하는 방법에대해 고민하는 대다수의 개발자들이 많은 도움이 되었길 바라며 본 포스팅을 마치고자 한다.
'안드로이드 > 일반' 카테고리의 다른 글
[Android] ContentProvider 누구보다 쉽게! (0) | 2019.06.03 |
---|---|
[Android] if문 vs switch문 (0) | 2019.04.01 |
[Android] Text, 하드코딩하지 말고 리소스화 해보자! (0) | 2019.03.12 |
[Android] Android Studio 'no idea annotations attached to the jdk 1.8' 에러 대처법 (4) | 2018.11.22 |
[Android] GDG Devfest 2018 참관 후기 (0) | 2018.11.13 |