View
2.769
Download
12
Category
Preview:
Citation preview
Day����������� ������������������ 8.����������� ������������������ (네트워크����������� ������������������ 상태에)����������� ������������������ 독립된����������� ������������������ 안드로이드����������� ������������������ 서비스����������� ������������������ 만들기
학습목표
• 네크워크가 불안정한 상태에서 동작하는 앱을 만들자!
• LocalStorage를 이용해서 서비스로 자동 동기화 시키자
• 다른 앱도 우리의 데이터를 사용할수 있게 공개하자
• 주기적으로 데이터가 들어오면 화면도 재갱신되게 만들자
이전까지의 상황
현재 Article을 받아오는 방법
스마트폰
서버
1. Homeview Activity가 Resume될 때
2. ActionBar의 refresh버튼을 누를 때
현재 APP 구조
Server
database
Activity
Proxy
Dao
현재 APP 구조
Server
database
Activity
Proxy
Dao
버튼을 클릭했을때
현재 APP 구조
Server
database
Activity
Proxy
Dao
1. Proxy에게 요청을 보낸다.
현재 APP 구조
Server
database
Activity
Proxy
Dao
2. Proxy가 서버에게 요청을 보낸다
현재 APP 구조
Server
database
Activity
Proxy
Dao
3. 서버가 Proxy에게 json데이터를 전달한다.
현재 APP 구조
Server
database
Activity
Proxy
Dao
4. Proxy가 Activity에게 json데이터를 전달한다.
현재 APP 구조
Server
database
Activity
Proxy
Dao
5. Activity가 Dao에게 json데이터를 전달한다.
현재 APP 구조
Server
database
Activity
Proxy
Dao
5. Dao가 json데이터를 DB에 저장한다.
내부 동작
Proxy.getJson()
Dao.insertJsonData()
1. Homeview Activity의 onResume()에서
2. ActionBar의 refresh버튼을 누를 때
Homview.refreshData()
현재처럼 Refresh를 누를때마다 데이터를 가져오는게 아니라
Server
database
Activity
Proxy
Dao
주기적으로 데이터를 전달받을 수 없을까?
Servicesection 1
백그라운드에서����������� ������������������ 계속����������� ������������������ 돌다!
주기적으로 서버로부터 최신데이터를 받아와서 업데이트 할 수 있는 어플리케이션을
만들어 보겠습니다.
Android Service
Service는 백그라운드에서 긴 기간동안 수행해야하는 연산을 하는 컴포넌트 사용자와 상호작용을 제공하지 않는 컴포넌트를 구현할때 사용
예) 네트워크 연산, 음악 재생, I/O 연산 수행, content provider와 상호작용 과 같은 모든 백그라운드 연산
Service의 두가지 형태STARTED BOUND
Activity같은 Component에서 startService() 메서드를 통해 시작할때
Component에서 bindService()메서드를 통해 시작할때
• 백그라운드에서 실행되기 때문에 호출한 컴포넌트가 사라져도 실행됨
• caller에게 결과값을 리턴하지 않음• 보통 한개의 연산을 수행할때 사용
• Client - Serivce 인터페이스 제공(send request, get results, IPC)
• Bind 되어있을 동안 서비스가 계속 살아있음. Bind 되어있는 서비스가 0개가 되었을때 서비스가 죽음
STARTED BOUND
Activity같은 Component에서 startService() 메서드를 통해 시작할때
Component에서 bindService()메서드를 통해 시작할때
• 백그라운드에서 실행되기 때문에 호출한 컴포넌트가 사라져도 실행됨
• caller에게 결과값을 리턴하지 않음• 보통 한개의 연산을 수행할때 사용
• Client - Serivce 인터페이스 제공(send request, get results, IPC)
• Bind 되어있을 동안 서비스가 계속 살아있음. Bind 되어있는 서비스가 0개가 되었을때 서비스가 죽음
Service의 두가지 형태
우리는 STARTED만 다룸
Android Service 구현하기
1. Service를 상속받는 SyncDataService 클래스를 하나 생성합니다.
2. Service를 사용하기 위해 AndroidManifest.xml에 코드를 추가합니다.
3. Service를 위해 필요한 메서드를 구현합니다
Android Service LifeCycle
Service Class 생성
• Service를 상속받는 클래스 SyncDataService를 생성합니다.
Android Manifest 파일 수정
• Android에서 Service를 사용하기 위해선 AndroidManifest.xml 파일에 등록을 해주어야 합니다. • application 태그 안에 넣어야 합니다.
구조 예시
Service 클래스를 상속받은 SyncDataService를 등록
구현해야할 메서드 추가
SyncDataService에서 코드를 Override 합니다
구현해야할 메서드 추가
SyncDataService에서 코드를 Override 합니다
• onCreate() : Service가 생성되었을 때 실행.
• onDestroy() : Service가 종료되었을 때 실행.
• onStartCommand() : 다른 컴포넌트에서
startService를 통해 시작했을때 실행.
구현해야할 메서드 추가
SyncDataService에서 코드를 Override 합니다
• onCreate() : Service가 생성되었을 때 실행.
• onDestroy() : Service가 종료되었을 때 실행.
• onStartCommand() : 다른 컴포넌트에서
startService를 통해 시작했을때 실행.
앞으로 이 3개의 메서드를 구현함으로써 기능을 완성시키겠습니다.
Service를 실행시키기(1)
암시적 인텐트를 활용하기 위해 intent-filter 태그를 추가합니다
AndroidManifest.xml
Service를 실행시키기(2)
Service가 실행되기 원하는 시점에 위의 코드를 추가해주도록 합니다.ex) HomeView의 onCreate()
HomeView.java
Service를 실행시키기(3)
실행이 되었는지 확인하기 위해서 로그를 남기도록 합니다.
SyncDataService.java
Article을 주기적으로 가져오자TimerTask 클래스와 Timer 클래스를 활용해 반복적인 작업을 실행하는 코드를 작성할 것입니다.
Article을 주기적으로 가져오자(1)Timer
본 예제에선 Timer(String name)을 활용하겠습니다.
Article을 주기적으로 가져오자(2)Timer의 메서드
… http://developer.android.com/reference/java/util/Timer.html
• schedule 메서드는 TimerTask (원하는 작업), 시작하기 원하는 때, 주기를 인자로 받아 작업을 수행합니다.
• 본 예제에선 schedule(TimerTask task, long delay, long period)를 활용하겠습니다.
Article을 주기적으로 가져오자(3)TimerTask
Runnable을 implements 하기 때문에 run() 메서드를 오버라이드 해줍니다.
Article을 주기적으로 가져오자(3)TimerTask
Runnable을 implements 하기 때문에 run() 메서드를 오버라이드 해줍니다.
생성자도 하나, 메서드도 3개를 지원하는 단순한 클래스 입니다.
TimerTask와 Timer 클래스를 활용해 주기적으로 메서드를 실행시키도록 합니다. 주기적으로 Log.i(TAGm “Hello”); 가 출력되는지 확인합니다.
SyncDataService.java
Article을 주기적으로 가져오자(4)
Service에서 Article 저장하기이전에 작성한 TimerTask class의 run()을 구현하여 Article을 저장해봅시다.
Service에서 Article 저장하기(1)Service와 Timer가 정상작동 하는것을 확인하였으니 이제 Article을 받아오는 로직을 추가하도록 합시다.
Proxy.getJson()
Dao.insertJsonData()
Article을 받아오는 메서드
Service에서 Article 저장하기(2)
SyncDataService.java
Proxy, Dao 인스턴스 생성을 위한 변수를 선언합니다.
Service에서 Article 저장하기(3)
SyncDataService.java
Proxy와 Dao에게 Application Context를 넘겨주고 생성합니다.Proxy와 Dao 클래스 내부에서 Application Context가 필요한 메서드가 있었습니다.
Service에서 Article 저장하기(3)
SyncDataService.java
TimerTask의 run() 메서드 안에 를 추가해 줍니다.Proxy.getJson()
Dao.insertJsonData()
Server
database
Activity
Proxy
Dao
Service는 주기적으로 요청을 보냅니다.
Service
Servicesection 1
백그라운드에서����������� ������������������ 계속����������� ������������������ 돌다!
마무리
우린 주기적으로 데이터를 받아올 수 있는 서비스를 구현했습니다
Service에 로그를 찍어 확인해 봅시다!
Content Providersection 2
다른����������� ������������������ 어플리케이션에게����������� ������������������ ����������� ������������������ 내����������� ������������������ 앱의����������� ������������������ 정보를����������� ������������������ 공유하다
database
Activity
Dao
다른앱에 우리의 데이터를 제공하고 싶다면?
database
Activity
Dao
다른앱에 우리의 데이터를 제공하고 싶다면?
데이터가 저장되었을때 화면을 자동으로 재갱신하고 싶다면?
database
Activity
Dao
다른앱에 우리의 데이터를 제공하고 싶다면?
데이터가 저장되었을때 화면을 자동으로 재갱신하고 싶다면?
데이터를 핸들링하는 템플릿을 유지하고 싶다면?
Content Provider의 역할
• 데이터 집합에 접근
• Data를 캡슐화 하고, Data의 보안을 위한 메커니즘을 제공
• 한 프로세스안의 데이터에 다른 프로세스가 접근하기 위한 표준 인터페이스
Content Provider Content Provider를 사용하기 위해 알아야할 클래스들
(1). ContentProvider
(2). ContentResolver
(3). Cursor
(4). Uri
Database에 접근
ContentProvider에 접근 Application이 데이터를 쉽게 핸들링
Resolver를 통해 얻어온 데이터를 조회
컨텐츠를 구분할 수 있는 식별자 전화번호부, DB.. 등등
Content Provider
동작 방식
ContentResolverApplication
DataBase
ContentProviderApplication
Application이 자신의 Resolver에게 데이터를 요청
1
URI
Content Provider
ContentResolverApplication
DataBase
ContentProviderApplication
ContentResolver가 URI에 적합한 어플리케이션의 ContentProvider를 찾아 데이터 요청
2
URI
동작 방식
Content Provider
ContentResolverApplication
DataBase
ContentProviderApplication
ContentProvider는 Resolver가 요청한 데이터를 Database에서 찾음
3
URI
동작 방식
Content Provider
ContentResolverApplication
DataBase
ContentProviderApplication
ContentProvider가 Resolver에게 데이터를 반환하고 Resolver는 데이터를 요청한 Application에게 Cursor 객체로 데이터를 반환
4Cursor
동작 방식
URI
Content Provider 특징ContentResolverApplication
DataBase
ContentProviderApplication
Cursor
1. ContentResolver 객체는 Provider 객체와 동일한 메서드를 갖는다.
2. ContentResolver 객체는 Create, Retrieve, Update, Delete (CRUD)를 제공함
ContentResolver.query() 메서드는 ContentProvider.query()의 메서드를 호출
Content Provider 학습순서
URI
ContentResolverApplication
DataBase
ContentProviderApplication
Cursor
1. Application에서 Content Resolver를 사용하는방법ContentResolver를 통해 ContentProvider에 접근할 수 있어야 한다
Content Provider 학습순서
URI
ContentResolverApplication
DataBase
ContentProviderApplication
Cursor
2. Content Provider를 제작하는 방법Custom Content Provider를 만들어 다른 어플리케이션에 인터페이스를 제공할 수 있어야 한다
ContentProvider에 접근해보자
ContentResolver의 메서드를 알아보고
메서드를 사용하기 위해 알아야할 개념들을 학습하자!
ContentResolver의 메서드ContentProvider
query() Provider를 통해 데이터를 전달받기 위한 함수 (Cursor 반환)
insert() Provider를 통해 데이터를 삽입함. (새로 삽입된 row의 URI를 반환)
update() Provider를 통해 데이터를 업데이트함. (업데이트된 로우의 개수를 반환)
delete() Provider를 통해 데이터를 삭제함. (삭제된 로우의 개수를 반환)
…. (더 있지만 우선 위의것이 기본)
ContentResolver의 메서드ContentProvider
query() Provider를 통해 데이터를 전달받기 위한 함수 (Cursor 반환)
insert() Provider를 통해 데이터를 삽입함. (새로 삽입된 row의 URI를 반환)
update() Provider를 통해 데이터를 업데이트함. (업데이트된 로우의 개수를 반환)
delete() Provider를 통해 데이터를 삭제함. (삭제된 로우의 개수를 반환)
…. (더 있지만 우선 위의것이 기본)
query()를 먼저 알아봄으로써 Content URI, Cursor 등 필요한 개념에 대해서 알아 봅시다.
연락처를 받아오는 App을 만들자
연락처 Provider : http://developer.android.com/reference/android/provider/ContactsContract.Contacts.html
百聞不如一見
Android 는 사용자 핸드폰에 저장된 연락처에 접근할 수 있는 Content Provider 를 이미 제공하고 있습니다.
따라서 우리는 그 연락처 Provider에 접근하는 Resolver 를 만들어
1. Application에서 Content Resolver를 사용하는방법ContentResolver를 통해 ContentProvider에 접근할 수 있어야 한다
위의 퀘스트를 달성하겠습니다.
새로운 프로젝트 생성
만들 메서드 2개!
1. Cursor getContactCursor ()ContentResolver를 통해 연락처 Provider에 데이터를 요청한 후 데이터 Cursor를 반환하는 메서드
2. void printLogContactData (Cursor contactData)contentProvider로 부터 Cursor형태로 넘어온 데이터를 Log에 출력하는 메서드
만들 메서드 2개!
1. Cursor getContactCursor ()ContentResolver를 통해 연락처 Provider에 데이터를 요청한 후 데이터 Cursor를 반환하는 메서드
2. void printLogContactData (Cursor contactData)contentProvider로 부터 Cursor형태로 넘어온 데이터를 Log에 출력하는 메서드
Cursor는 뭔데?
Cursor란 무엇일까요.
Cursor란 무엇일까요.d.android는 말합니다.
Cursor란 무엇일까요.
Database query로 부터 반환된 결과에 접근하는 인터페이스라고..
d.android는 말합니다.
(웅장하게)
Android 내부로 들어가봅시다.
Cursor란 무엇일까요?
Application
DBDB야 데이터좀 줄래?! (query)
Cursor란 무엇일까요?
Application
DBData
자. 데이터!
Cursor란 무엇일까요?
DBData
Application
사용하기 너무 불편해ㅠㅠ
Cursor란 무엇일까요?
DB
ApplicationData
Cursor Cursor 객체를 통해 데이터를 사용하자
Cursor에 대한 더 자세한 정보 : http://developer.android.com/reference/android/database/Cursor.html
Manifest파일에 권한 추가
getContactCursor 구현(1)
Mac기준 : command + shift + o 를 눌러 Import하지 않은 클래스를 Import
ContentResolver를 통해 연락처 Provider에 데이터를 요청한 후, 데이터 Cursor를 반환하는 메서드
함수를 작성합니다.
getContactCursor 구현(2)ContentResolver를 통해 연락처 Provider에 데이터를 요청한 후, 데이터 Cursor를 반환하는 메서드
Uri contactURI 는 Provider의 데이터를 식별하기 위한 URI 입니다.ContactsContract.Contacts.CONTENT_URI 는 연락처 정보 테이블의 위치를 의미합니다.
getContactCursor 구현(3)ContentResolver를 통해 연락처 Provider에 데이터를 요청한 후, 데이터 Cursor를 반환하는 메서드
Projection 은 Provider로 부터 획득하고 싶은 정보를 서술합니다.
—————>다양한 정보를 제공
getContactCursor 구현(4)ContentResolver를 통해 연락처 Provider에 데이터를 요청한 후, 데이터 Cursor를 반환하는 메서드
getContentResolver() 를 통해 Resolver 객체를 획득한 후 query() 메서드를 사용합니다.
getContactCursor 구현(4)ContentResolver를 통해 연락처 Provider에 데이터를 요청한 후, 데이터 Cursor를 반환하는 메서드
getContentResolver() 를 통해 Resolver 객체를 획득한 후 query() 메서드를 사용합니다.
SQL query 와 비교해서 좀 더 자세히 설명하겠습니다.
getContactCursor 구현(4)ContentResolver를 통해 연락처 Provider에 데이터를 요청한 후, 데이터 Cursor를 반환하는 메서드
query() 인자값 SELECT 비고
Uri FROM table_name Uri 는 provider의 테이블에 접근하는 정보
projection col, col, col, … 반환받길 원하는 col을 서술한다.
selectionWHERE col = value
WHERE 뒤에 오는 문장을 표현한다. 변수는 ? 로서 표현
selectionArgs selection의 ?에 매칭되어 값이 전달된다
sortOrder Order By col, col… sortOrder 에 따라서 Cursor가 정렬되어 반환됨
getContactCursor 구현(5)ContentResolver를 통해 연락처 Provider에 데이터를 요청한 후, 데이터 Cursor를 반환하는 메서드
SELECT _ID, display_name FROM contacts ORDER BY display_name ASC;
null일 경우 연결 실패
.query(contactURI, projection, null, null, Contacts.DISPLAY_NAME+” asc”);
만들 메서드 2개!
1. Cursor getContactCursor ()ContentResolver를 통해 연락처 Provider에 데이터를 요청한 후 데이터 Cursor를 반환하는 메서드
2. void printLogContactData (Cursor contactData)contentProvider로 부터 Cursor형태로 넘어온 데이터를 Log에 출력하는 메서드
printLogContactData 구현(1)contentProvider로 부터 Cursor형태로 넘어온 데이터를 Log에 출력하는 메서드
id와 displayName의 인덱스 정보를 저장할 변수를 선언합니다.
printLogContactData 구현(1)contentProvider로 부터 Cursor형태로 넘어온 데이터를 Log에 출력하는 메서드
Cursor가 null일 경우 연결이 실패한 경우입니다.
null일 경우 연결 실패
printLogContactData 구현(1)contentProvider로 부터 Cursor형태로 넘어온 데이터를 Log에 출력하는 메서드
결과값의 개수가 0개일 경우도 처리해 줍니다.
Cursor의 getCount() 메서드를 활용해 크기를 구합니다
printLogContactData 구현(1)contentProvider로 부터 Cursor형태로 넘어온 데이터를 Log에 출력하는 메서드
나머지 경우에 원하는 코드를 작성해 주도록 합시다.
1. idIndex와 displayNameIndex의 값을 구합니다.
2. 로그에 결과를 출력합니다.
printLogContactData 구현(1)contentProvider로 부터 Cursor형태로 넘어온 데이터를 Log에 출력하는 메서드
getColumnIndex()을 통해 id와 displayName의 인덱스를 구합니다.
printLogContactData 구현(1)contentProvider로 부터 Cursor형태로 넘어온 데이터를 Log에 출력하는 메서드
moveToNext() 메서드를 통해 결과값에 접근하도록 합니다.
printLogContactData 구현(1)contentProvider로 부터 Cursor형태로 넘어온 데이터를 Log에 출력하는 메서드
getLong(), getString() 메서드를 통해 Cursor로부터 데이터를 회수합니다.
결과
연락처에있는 모든 목록을 가져와 출력합니다.
1. Application에서 Content Resolver를 사용하는방법ContentResolver를 통해 ContentProvider에 접근할 수 있어야 한다
1. Cursor getContactCursor ()2. void printLogContactData (Cursor contactData)메서드를 만들어 봄으로써
을 학습했습니다
Content Provider 만들어 보기Custom Content Provider를 만들어 다른 어플리케이션에 인터페이스를 제공할 수 있어야 한다
Content Provider를 만들기 전에
• Content Provider가 정말 필요한지 생각해보자필요한 경우 1. 다른 어플리케이션에게 복잡한 데이터, file을 제공하길 원한다면. 2. 사용자가 당신의 앱에서 다른 앱으로 복잡한 데이터를 복사하길 원한다면. 3. Search Framework를 사용해서 custom search를 제공하길 원한다면.
• 이미 제공하는 Provider가 있을경우 굳이 만들지 말자Calendar, Contacts 같이 이미 제공하는 Provider들을 찾아보자
Content Provider 만들기 순서
• NextgramProvider를 만들자.• Dao를 분리하기
• Contract Class 만들기
• Content Provider 상속&구현하기
• Dao를 분리하기
현재 있는 Dao.java를 복사해 ProviderDao.java를 만듭니다.
• Dao를 분리하기
클래스이름과 생성자이름을 수정해 에러를 제거합니다.
• 현재 NEXTGRAM의 DAO클래스는 충실한 DAO클래스 일까?
아니다! 1. Database에 접근하는 역할, 데이터를 Mashaling, Unmashaling하는 역할 등 여러가지 역할을 동시에 가지고 있다.
• Dao를 분리하기
따라서!
Database와 연동
json데이터 객체화
등등….
하게 분리하겠습니다.
• Dao를 분리하기
Dao.javaProviderDao.java
NextgramProvider.java
• Dao를 분리하기
NextgramProvider라는 이름의 새로운 클래스를 생성합니다.
• Content Provider를 상속받습니다.
• unimplemented methods를 구현하도록 합니다
onCreate query getType insert delete update
• Dao를 분리하기
• Dao를 분리하기
NextgramProvider 에게 필요한 기능을 ProviderDao로부터 복사해옵니다.Database와 통신하기 위한
• sqLiteInitialize • tableCreate • isTableExist
NextgramProvider.java
• Dao를 분리하기
NextgramProvider 에게 필요한 변수를 생성해 줍니다.
NextgramProvider.java
• Dao를 분리하기
NextgramProvider의 onCreate를 구현합니다.
NextgramProvider.java
• Contract class는 Content Provider에서 필요한 상수값을 지정해두는 클래스입니다.
• 외부의 어플리케이션에서 Provider를 사용하기 위해 필요한 값들이 지정되어 있습니다.
연락처 Provider의 Contract class 사용 예제
• Contract Class 만들기
NextgramContract 라는 public final class 를 만들어 줍시다
• Contract Class 만들기
NextgramContract 에 AUTHORITY, CONTENT_URI에 대한 정보를 입력합니다.
• Contract Class 만들기
NextgramContract.java
잠깐! Content URI, Authority?!
Content URI를 디자인하자
• Content URI는 provider안의 데이터를 식별하는 URI이다.
• Provider의 이름을 의미하는 Authority와 테이블이나 파일을 의미하는 Path로 구성되어 있다.
Authority Path+Content URI
Content URI를 디자인하자
Authority Path+Content URI
org.nhnnext.nextgram.provider/table1
Authority는 다른 프로바이더와 충돌을 피하기 위해 “Android 패키지 이름 + 앱이름” 을 추천한다
예시 :
Content URI를 디자인하자
Content URI 패턴
content://org.nhnnext.nextgram.provider/table1
content://org.nhnnext.nextgram.provider/table2/dataset1
content://org.nhnnext.nextgram.provider/table2/dataset2
content://org.nhnnext.nextgram.provider/table3
table1을 요청.
dataset1이라 불리는 table을 요청
dataset2라 불리는 table을 요청
table3을 요청함.
URI를 통해 테이블에 접근
URI를 통해 각 열에 접근content://org.nhnnext.nextgram.provider/table1/1 table1을 요청.
테이블 URI : content://<authority>/<path> 한 열의 URI : content://<authority>/<path>/<id>
#은 모든 숫자에 매칭 *은 모든 숫자, 문자에 매칭
Inner class로 BaseColumns를 상속받은 Articles 클래스를 작성합니다.
• Contract Class 만들기
NextgramContract.java
테이블의 컬럼속성인 _ID, TITLE, WRITER, ID, CONTENT, WRITER_DATE, IMAGE_NAME와 매치되는 변수를 선언합니다.
• Contract Class 만들기
NextgramContract.java
Articles 테이블의 아이템에 연결되는 CONTENT_URI를 작성합니다.
• Contract Class 만들기
NextgramContract.java
PROJECTION_ALL에 대한 정보를 작성해 둡니다.
• Contract Class 만들기
NextgramContract.java
기본적인 정렬은 _ID를 기준으로 하도록 합니다.
• Contract Class 만들기
NextgramContract.java
이렇게 만들어진 Contract Class는 Provider에 접근하기 위한 API라고 생각하면 편합니다.
• Contract Class 만들기
다음으론 NextgramProvider의
onCreate query getType insert delete update
이렇게 만들어진 Contract Class는 Provider에 접근하기 위한 API라고 생각하면 편합니다.
• Contract Class 만들기
다음으론 NextgramProvider의
onCreate query getType insert delete update
MIME TYPE을 지원하지 않음.
아직 기능이 없음아직 기능이 없음
이렇게 만들어진 Contract Class는 Provider에 접근하기 위한 API라고 생각하면 편합니다.
• Contract Class 만들기
다음으론 NextgramProvider의 onCreate query insert
를 구현하겠습니다.
• Content Provider 상속&구현하기
Android Manifest 파일안에
<manifest> 안에 위의 퍼미션과
Provider가 지정되어야 합니다.
• Content Provider 상속&구현하기
NextgramProvider.java
query, insert에서 사용할 URI정보를 관리할 Uri Matcher 객체를 생성합니다.
• Content Provider 상속&구현하기
NextgramContract.java
Resolver를 통해 요청이 들어올때
“org.nhnnext.nextgram.provider/Articles”는 1 (ARTICLE_LIST) 처리“org.nhnnext.nextgram.provider/Articles/#”는 2 (ARTICLE_ID) 처리
• Content Provider 상속&구현하기
다음으로 insert를 구현하겠습니다.
• Content Provider 상속&구현하기
NextgramProvider.java
처음보는 ContentValues가 나왔습니다.나중에 설명해 드릴게요!
• Content Provider 상속&구현하기
NextgramProvider.java
• Content Provider 상속&구현하기
NextgramProvider.java
• Content Provider 상속&구현하기
NextgramProvider.java
• Content Provider 상속&구현하기
insert는 구현이 완료되었으니 query를 구현하겠습니다.
• Content Provider 상속&구현하기
NextgramProvider.java
Uri uri 객체를 통해 원하는 요청이 무엇인지 검사합니다.
• Content Provider 상속&구현하기
NextgramProvider.java
URI가 “org.nhnnext.nextgram.provider” 일때 URI_MATCHER의 match()는 ARTICLE_LIST(1)을 반환합니다.
• Content Provider 상속&구현하기
NextgramProvider.java
sortOrder값이 없다면 _ID를 기준으로 정렬합니다.
NextgramContract.java
• Content Provider 상속&구현하기
NextgramProvider.java
ARTICLE_ID 일 때에는 한개의 게시글을 가져오도록 코드를 작성합니다.
• Content Provider 상속&구현하기
ARTICLE_LIST, ARTICLE_ID 등 다양한 Uri에 대해 값들을 준비한 후
Database에 Query를 보내봅시다.
• Content Provider 상속&구현하기
NextgramProvider.java
요기에 작성!
• Content Provider 상속&구현하기
NextgramProvider.java
database.query를 통해 Table, projection, selection, selectionArgs, sortOrder를 지정하고 query를 보냅니다.
• Content Provider 상속&구현하기
NextgramProvider.java
반환된 cursor를 return 해주면 완료!
• Content Provider 상속&구현하기
NextgramProvider.java의 insert, query를 구현 했으니 ProviderDao.java를 수정하도록 하겠습니다.
• Content Provider 상속&구현하기
ProviderDao.java의 • sqLiteInitialize • tableCreate • isTableExist
메서드를 제거해 줍니다.
Database와 직접 연결하는것은 NextgramProvider의 역할입니다.
• Content Provider 상속&구현하기
ProviderDao.java의 • insertJsonData • getArticleList • getArticle
메서드를 수정할 겁니다.
insert
query
• Content Provider 상속&구현하기
1. insertJsonData 수정
• Content Provider 상속&구현하기
기존 Dao.java에서는 database에 직접 insert하는 쿼리에 컬럼의 값들을 직접 붙여 날리는 방법을 사용했습니다.
하지만 ContentResolver를 이용하면 database에 직접 접근할 수 없으므로 컬럼 값들을 ContentValues에 담아 전달해야 합니다.
• Content Provider 상속&구현하기
ContentValues
공식 레퍼런스
백문이 불여일견
• Content Provider 상속&구현하기
Database에 직접 접근하던 코드를 Resolver를 통해 Provider를 사용하도록 수정합니다
(기존) Dao.java - insertJsonData 메서드 (insert 쿼리를 만들어 database에 날림)
• Content Provider 상속&구현하기
Database에 직접 접근하던 코드를 Resolver를 통해 Provider를 사용하도록 수정합니다
(수정) ProviderDao.java - insertJsonData 메서드 (각 컬럼의 값들을 ContentValues의 객체인 values에 담아 전달)
• Content Provider 상속&구현하기
2. getArticleList 수정
• Content Provider 상속&구현하기
getArticleList 메서드 틀린 그림 찾기
ProviderDao.java Dao.java
• Content Provider 상속&구현하기
Dao.java
ProviderDao.java
• Content Provider 상속&구현하기
ProviderDao.java
Dao.java
• Content Provider 상속&구현하기
2. getArticleByArticleNumber 수정
• Content Provider 상속&구현하기
ProviderDao.java Dao.java
getArticleByArticleNumber 메서드 틀린 그림 찾기
• Content Provider 상속&구현하기
Dao.java
ProviderDao.java
Content Providersection 2
다른����������� ������������������ 어플리케이션에게����������� ������������������ ����������� ������������������ 내����������� ������������������ 앱의����������� ������������������ 정보를����������� ������������������ 공유하다
마무리
Server
database
Activity
Proxy
Content Provider를 통해 DB에 접근할 수 있게 됬습니다.
Service
Content Provider
ProviderDao
변경된 앱의 구조
database
Activity
Dao
다른앱에 우리의 데이터를 제공하고 싶다면?
데이터가 저장되었을때 화면을 자동으로 재갱신하고 싶다면?
데이터를 핸들링하는 템플릿을 유지하고 싶다면?
database
Activity
Dao
다른앱에 우리의 데이터를 제공하고 싶다면?
데이터가 저장되었을때 화면을 자동으로 재갱신하고 싶다면?
데이터를 핸들링하는 템플릿을 유지하고 싶다면?
database
Activity
Dao
다른앱에 우리의 데이터를 제공하고 싶다면?
데이터가 저장되었을때 화면을 자동으로 재갱신하고 싶다면?
데이터를 핸들링하는 템플릿을 유지하고 싶다면?
database
Activity
Dao
다른앱에 우리의 데이터를 제공하고 싶다면?
데이터가 저장되었을때 화면을 자동으로 재갱신하고 싶다면?
데이터를 핸들링하는 템플릿을 유지하고 싶다면?
데이터가 저장되었을때 화면을 자동으로 재갱신하고 싶다면?
Cursor Adaptersection 3
데이터가����������� ������������������ 삽입되면����������� ������������������ 화면에����������� ������������������ 자동으로����������� ������������������ ����������� ������������������ 재갱신됩니다
데이터가 저장되었을때 화면을 자동으로 재갱신하고 싶다면?
HomeViewAdapter를 CursorAdpater로 변경하자
HomeView 변경
Cursor Adapter는 데이터를 가져올때마다 갱신할 필요가 없습니다. 위의 주석처리된 부분을 삭제해주도록 합니다.
HomView.java
HomeView 변경
위의 명령을 onCreate의 마지막 부분에 추가해주도록 합니다. 이제, listViewSimple1()을 변경해야 합니다.
HomView.java
HomeView 변경
CursorAdapter로 사용하기 위해 코드를 변경합니다. HomeViewAdapter는 context, cursor, layout 파일을 인자로 받습니다.
HomView.java
CursorAdapter를 만들기 위해 HomeView는 준비를 끝냈으니 ArrayAdapter를 상속받은 HomeViewAdapter를 수정하도록 합니다.
CursorAdapter 변경
CursorAdapter를 상속받도록 변경합니다.
CursorAdapter.java
CursorAdapter 변경
1. Context, Cursor, XML layoutID를 받도록 생성자를 변경합니다. 2. LayoutInflater도 미리 생성해두도록 합니다.
CursorAdapter.java
CursorAdapter 변경
CursorAdapter를 상속받으면 newView, bindView를 구현해야합니다. 이 둘은 기존의 getView의 기능을 분리해 둔 것입니다.
CursorAdapter.java
getView 메서드는 지우도록합니다
newView, bindView
newView는 처음 view가 생성될때 실행됩니다.
bindView는 이미 뷰가 생성되어있으면 실행합니다.
newView, bindView를 구현하기 전에!
ViewHolder Pattern
Adapter를 갱신할때마다 findViewById()를 사용해 성능이 저하되는것을 막기 위해 ViewHolder Pattern을 사용하도록 하겠습니다.
View객체를 재사용하기 위한 목적
기존의 HomeViewAdapter.java의 getView()
CursorAdapter 변경
CursorAdapter.java안에 ViewHolderItem 클래스를 작성합니다. 다음슬라이드부터 적극적으로 활용됩니다.
CursorAdapter.java
CursorAdapter 변경
xml파일로부터 inflate한 View를 만들어 줍니다. 반환을 위한 목적의 뷰입니다.
CursorAdapter.java
CursorAdapter 변경
ViewHolderItem 객체를 생성합니다.
CursorAdapter.java
CursorAdapter 변경
1. ViewHolderItem 객체에게 resourceID에 대한 정보를 입력해줍니다. 2. View에게 setTag()를 활용해 입력해둡니다.
CursorAdapter.java
newView를 구현했으니 bindView를 구현합니다.
CursorAdapter 변경
Cursor로부터 View에 사용할 데이터를 저장합니다.
CursorAdapter.java
CursorAdapter 변경
getTag를 통해 viewHolderItem 객체를 획득한 후 articleNumber, writer, title을 셋팅합니다.
CursorAdapter.java
CursorAdapter 변경
ImageView도 셋팅하도록 합니다.
CursorAdapter.java
마지막으로 HomeView에서 Item을 클릭했을때 ArticleNumber를 받아오는 부분을 수정하도록 합니다.
CursorAdapter.java
이로써 ArrayAdpater기반의 HomeViewAdapter를 CursorAdapter 기반으로 변경 완료!
Cursor Adapter 영상
왜 Cursor Adapter 일까?
현재사용하는 Adpater
ArrayAdapter배열 데이터를 위젯에 공급해주는 Adapter
왜 Cursor Adapter 일까?
현재사용하는 Adpater
ArrayAdapter배열 데이터를 위젯에 공급해주는 Adapter
Array
DB로부터 데이터를 획득해서 데이터를 Array로 변환.
왜 Cursor Adapter 일까?
현재사용하는 Adpater
ArrayAdapter배열 데이터를 위젯에 공급해주는 Adapter
ArrayAdapterArray
ArrayAdapter눈 Array의 데이터와 xml 파일을 결합.
list_item.xml
왜 Cursor Adapter 일까?
현재사용하는 Adpater
ArrayAdapter배열 데이터를 위젯에 공급해주는 Adapter
ArrayAdapterArray
list_item.xml
사용자의 화면에 보여줌.
왜 Cursor Adapter 일까?
현재사용하는 Adpater
ArrayAdapter배열 데이터를 위젯에 공급해주는 Adapter
Array 정보는 DB정보가 변경되어도 사용자 화면을 갱신하기 어려움
Cursor
왜 Cursor Adapter 일까?
CursorAdapterCursor로 부터 획득한 데이터를 위젯에 공급해주는 Adapter
CursorAdapter
list_item.xml
DB Uri를 가진 Cursor를 통해 DB와 연결됨.
왜 Cursor Adapter 일까?
CursorAdapterCursor로 부터 획득한 데이터를 위젯에 공급해주는 Adapter
Cursor CursorAdapter
list_item.xml
사용자의 화면에 보여줌.
왜 Cursor Adapter 일까?
CursorAdapterCursor로 부터 획득한 데이터를 위젯에 공급해주는 Adapter
Cursor CursorAdapter
list_item.xml
DB의 내용이 갱신될때마다 사용자의 화면을 변경하기 용이함
왜 Cursor Adapter 일까?
CursorAdapter와 ContentProvider사이의 패턴
Cursor CursorAdapter
list_item.xml
ContentProvider
Cursor Adapter 와 Content Provider
상황 : 사용자A가 HomeView를 보고있을때 사용자B가 새로운 글을 입력하는 상황
사용자B가 게시글을 작성하면 서버에 게시글이 업로드됨.
사용자B
Server
서비스가 동작하면서 사용자A의 어플리케이션이 서버에서 게시글을 받아옴.
Server
사용자 A
사용자A의 어플리케이션의 ContentProvider를 통해 Database에 insert됨
사용자 A
사용자A의 어플리케이션의 ContentProvider를 통해 Database에 insert됨
사용자 A
insert될떄 notifyChange동작
Cursor CursorAdapter
list_item.xml
ContentProvider
데이터가 변경됐어!
Cursor를 통해 연결되어있는 CursorAdapter가 동작후 뷰 재갱신
Cursor CursorAdapter
list_item.xml
ContentProvider
알겠어!
Cursor를 통해 연결되어있는 CursorAdapter가 동작후 뷰 재갱신
Cursor CursorAdapter
list_item.xml
ContentProvider
CursorAdapter와 ContentProvider사이에는 무슨일이 있는걸까?
Cursor를 통해 연결되어있는 CursorAdapter가 동작후 뷰 재갱신
Publisher/SubscribePattern
ContentProvider CursorAdapter
사이의
publisher/SubscribePattern
ContentProvider CursorAdapter
사이의
1. Content Provider가 notifyChange메서드를 호출한다. 2. 등록되어있던 Subscribe들의 OnChange()가 호출된다. 3. CursorAdapter는 내부적으로 notifyDataSetChanged()를 호출한다.
CursorAdapter
ContentProvider Subscribe
Subscribe
Register
Notify
Cursor Adaptersection 3
데이터가����������� ������������������ 삽입되면����������� ������������������ 화면에����������� ������������������ 자동으로����������� ������������������ ����������� ������������������ 재갱신됩니다
마무리
Recommended