SlideShare a Scribd company logo
1 of 19
Pro Android Performance Optimization
Jun Chang Wook
TITLE : Android 개발 최초 고려사항
TITLE : Android 최적화 소스 개발 시 해야 될 일
TITLE : 재귀적 호출 방법을 순환 호출 방법으로 변경
REASON
TITLE : Android SparseArray 사용
REASON
TITLE : StrictMode 사용
TITLE :+ 연산자
System.out.println(“y의 값은: ” + y);
Log.e(“”, A+B+C+D+E+F+G+H+I+J+K+L+M+N);
+ 하는 String 의 갯수가 늘어나면 늘어날수록
GC 대상 object 수도 함께 늘어나고 그만큼 memory 할당도 추가로 된다.
REASON
TITLE : DB compileStatement
boilerplate
String sql = "INSERT INTO tip (tip_creator, symbol, target_price, reason) VALUES (?, ?, ?, ?)";
StockDatabase dbHelper = new StockDatabase(this.getApplicationContext());
SQLiteDatabase db = dbHelper.openDatabase();
SQLiteStatement stmt = db.compileStatement(sql);
stmt.bindString(1, "USERNAME");
stmt.bindString(2, symbol);
stmt.bindDouble(3, targetPrice);
stmt.bindString(4, reason);
stmt.execute();
stmt.close();
db.close();
TITLE : Type
TITLE : Broadcast Receiver (Battery)
enableBatteryReceiver(true);
enableBatteryReceiver(false);
TITLE : wakelock (Battery)
TITLE : wakelock 해제(Battery)
Layout
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:keepScreenOn="true">
Source
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
TITLE : 그래픽
TITLE : Memory 관리
REFERENCE OBJECT
1. Strong Reference
Strong Reference는 new를 이용해 생성된 객체는 GC에서 무조건 제외되기 때문에 메모리 누수(Memory Leak)을
방지하기 위해서는 이 참조를 주의해서 보아야 합니다. 이 참조를 지워주지 않으면 GC에 의해 수거되지 않고 남아
있기 때문에 메모리 누수를 유발할 수 있습니다.
2. Soft Reference
SoftReference는 다음과 같이 객체에 Reference를 넘겨줌으로서 생성할 수 있습니다.
SoftReference object = new SoftReference(new Object()); 이 참조는 메모리가 충분하다면 GC에 의해서 수거되지
않고, 메모리에 여유가 없다면 GC에 의해 수거됩니다.
3. Weak Reference
WeakReference는 SoftReference와 유사하지만 GC가 발생되기 전까지는 참조를 유지하고 GC가 발생하면 무조건
회수된다는 점에서 차이가 있습니다. 이는 유용하게 쓰일 수 있는데, 짧은 시간, 자주 쓰일 수 있는 객체를 이용할
때 유용하게 사용될 수 있습니다.
TITLE : Memory 관리
class BitmapWorkerTask extends AsyncTask {
private final WeakReference imageViewReference;
private int data = 0;
public BitmapWorkerTask(ImageView imageView){
imageViewReference = new WeakReference(imageView);
}
@Override protected
Bitmap doInBackground( Integer... params){
data = param[0];
return decodeSampledBitmapFromResource( getResources(), data, 100, 100);
}
@Override protected void onPostExecute( Bitmap bitmap){
if( imageViewReference != null && bitmap != null){
final ImageViewReference imageView = imageViewReference.get();
if( imageView != null){
imageView.setImageBitmap( bitmap);
}
}
}
}
TITLE : Memory 관리
LruCache는 LinkedHashMap을 사용하여 최근에 사용된 object의 strong reference를 보관하고 있다가 정
해진 사이즈를 넘어가게 되면
가장 최근에 사용되지 않은 놈부터 쫓아내는 LRU 알고리즘을 사용하는 메모리 캐시다
Android.util.LruCache<K, V>
LruCache의 캐시사이즈를 정하기 위해서는 다음 요소들을 고려해야 한다.
1. 우리 앱에서 앞으로 메모리를 얼마나 써야 되는가 ?.
2. 얼마나 많은 이미지들이 한 화면에 보일 것인가?
3. 얼마나 많은 이미지들이 다음에 보여주기 위해 준비되어야 하는가?
4. 화면 해상도가 어떻게 되는가?
5. 각 이미지 마다 메모리를 얼마나 차지하는가?
6. 이미지는 얼마나 자주 액세스 되는가?
위에 내용을 고려해서 정해야 하며 어느정도 캐시사이즈가 적당한지 공식은 없고
앱의 메모리 사용량을 측정해보면서 적당히 정해야 한다.
당연한 말이겠지만 너무 사이즈를 작게 하면 괜히 오버헤드만 발생하게 되고
사이즈를 너무 크게 했다가 OutOfMemory Exception을 보게 될 거다.
많은 양의 저해상도 이미지를 미리 보여주고 백그라운드로 고해상도 이미지를 로드 하는 방법이 좋을 수도 있다.
TITLE : Memory 관리
Android.util.LruCache<K, V>
private LruCache mMemoryCache;
@Override
protected void onCreate(Bundle savedInstanceState) {
...
// Get memory class of this device, exceeding this amount will throw an
// OutOfMemory exception.
final int memClass = ((ActivityManager) context.getSystemService(
Context.ACTIVITY_SERVICE)).getMemoryClass();
// Use 1/8th of the available memory for this memory cache.
final int cacheSize = 1024 * 1024 * memClass / 8;
mMemoryCache = new LruCache(cacheSize) {
@Override
protected int sizeOf(String key, Bitmap bitmap) {
// The cache size will be measured in bytes rather than number of items.
return bitmap.getByteCount();
}
};
...
}
public void addBitmapToMemoryCache(String key, Bitmap bitmap) {
if (getBitmapFromMemCache(key) == null) {
mMemoryCache.put(key, bitmap);
}
}
public Bitmap getBitmapFromMemCache(String key) {
return mMemoryCache.get(key);
}
Reference 자료
출처: http://itmining.tistory.com/10 [IT 마이닝]
https://github.com/apress/pro-android-apps-perf-optimization
안드로이드 앱 성능 최적화 출판사 프리렉
출처: http://dpug.tistory.com/33#.Wi5rJ0pl-Hs [퍼그의 전초기지]
출처: http://aroundck.tistory.com/11 [돼지왕 왕돼지 놀이터]
https://www.codota.com/android/methods/android.database.sqlite.SQLiteDatabase/compileStatement
출처: http://caliou.tistory.com/122 [미녀개발자님의 블로그]
https://www.androidpub.com/2426245
Jun Chang Wook
THANK YOU

More Related Content

Similar to Pro android performance optimization 20171213

게임 데이터 분석을 위한 Data Lake 구축과 Machine Learning 을 활용한 분석 Hands on Lab (안효빈 솔루션즈 ...
게임 데이터 분석을 위한 Data Lake 구축과 Machine Learning 을 활용한 분석 Hands on Lab (안효빈 솔루션즈 ...게임 데이터 분석을 위한 Data Lake 구축과 Machine Learning 을 활용한 분석 Hands on Lab (안효빈 솔루션즈 ...
게임 데이터 분석을 위한 Data Lake 구축과 Machine Learning 을 활용한 분석 Hands on Lab (안효빈 솔루션즈 ...Amazon Web Services Korea
 
[NDC2015] 언제 어디서나 프로파일링 가능한 코드네임 JYP 작성기 - 라이브 게임 배포 후에도 프로파일링 하기
[NDC2015] 언제 어디서나 프로파일링 가능한 코드네임 JYP 작성기 - 라이브 게임 배포 후에도 프로파일링 하기[NDC2015] 언제 어디서나 프로파일링 가능한 코드네임 JYP 작성기 - 라이브 게임 배포 후에도 프로파일링 하기
[NDC2015] 언제 어디서나 프로파일링 가능한 코드네임 JYP 작성기 - 라이브 게임 배포 후에도 프로파일링 하기Jaeseung Ha
 
Amazon Rekognition을 이용하여 인공지능 안면 인식 키오스크 만들기 - 강정희 (AWS 솔루션즈 아키텍트)
Amazon Rekognition을 이용하여 인공지능 안면 인식 키오스크 만들기 - 강정희 (AWS 솔루션즈 아키텍트)Amazon Rekognition을 이용하여 인공지능 안면 인식 키오스크 만들기 - 강정희 (AWS 솔루션즈 아키텍트)
Amazon Rekognition을 이용하여 인공지능 안면 인식 키오스크 만들기 - 강정희 (AWS 솔루션즈 아키텍트)Amazon Web Services Korea
 
권기훈_포트폴리오
권기훈_포트폴리오권기훈_포트폴리오
권기훈_포트폴리오Kihoon4
 
안드로이드스터디 1
안드로이드스터디 1안드로이드스터디 1
안드로이드스터디 1jangpd007
 
딥러닝 세계에 입문하기 위반 분투
딥러닝 세계에 입문하기 위반 분투딥러닝 세계에 입문하기 위반 분투
딥러닝 세계에 입문하기 위반 분투Ubuntu Korea Community
 
배워봅시다 머신러닝 with TensorFlow
배워봅시다 머신러닝 with TensorFlow배워봅시다 머신러닝 with TensorFlow
배워봅시다 머신러닝 with TensorFlowJang Hoon
 
[2017 AWS Startup Day] 스타트업이 인공지능을 만날 때 : 딥러닝 활용사례와 아키텍쳐
[2017 AWS Startup Day] 스타트업이 인공지능을 만날 때 : 딥러닝 활용사례와 아키텍쳐[2017 AWS Startup Day] 스타트업이 인공지능을 만날 때 : 딥러닝 활용사례와 아키텍쳐
[2017 AWS Startup Day] 스타트업이 인공지능을 만날 때 : 딥러닝 활용사례와 아키텍쳐Amazon Web Services Korea
 
AWS기반 서버리스 데이터레이크 구축하기 - 김진웅 (SK C&C) :: AWS Community Day 2020
AWS기반 서버리스 데이터레이크 구축하기 - 김진웅 (SK C&C) :: AWS Community Day 2020 AWS기반 서버리스 데이터레이크 구축하기 - 김진웅 (SK C&C) :: AWS Community Day 2020
AWS기반 서버리스 데이터레이크 구축하기 - 김진웅 (SK C&C) :: AWS Community Day 2020 AWSKRUG - AWS한국사용자모임
 
AWS기반 서버리스 데이터레이크 구축하기 - 김진웅 (SK C&C) :: AWS Community Day 2020
AWS기반 서버리스 데이터레이크 구축하기 - 김진웅 (SK C&C) :: AWS Community Day 2020AWS기반 서버리스 데이터레이크 구축하기 - 김진웅 (SK C&C) :: AWS Community Day 2020
AWS기반 서버리스 데이터레이크 구축하기 - 김진웅 (SK C&C) :: AWS Community Day 2020Jinwoong Kim
 
Software Architect day - 웹 프레임워크 종결 - metaworks3
Software Architect day - 웹 프레임워크 종결 -  metaworks3Software Architect day - 웹 프레임워크 종결 -  metaworks3
Software Architect day - 웹 프레임워크 종결 - metaworks3uEngine Solutions
 
Tiny ml study 20201031
Tiny ml study 20201031Tiny ml study 20201031
Tiny ml study 20201031ByoungHern Kim
 
[E-commerce & Retail Day] 인공지능서비스 활용방안
[E-commerce & Retail Day] 인공지능서비스 활용방안[E-commerce & Retail Day] 인공지능서비스 활용방안
[E-commerce & Retail Day] 인공지능서비스 활용방안Amazon Web Services Korea
 
Real-time Big Data Analytics Practice with Unstructured Data
Real-time Big Data Analytics Practice with Unstructured DataReal-time Big Data Analytics Practice with Unstructured Data
Real-time Big Data Analytics Practice with Unstructured DataTed Won
 
Hacosa js study 4주차
Hacosa js study 4주차Hacosa js study 4주차
Hacosa js study 4주차Seong Bong Ji
 
About Visual C++ 10
About  Visual C++ 10About  Visual C++ 10
About Visual C++ 10흥배 최
 
퍼블리셔, 프론트엔드개발을 시작하다
퍼블리셔, 프론트엔드개발을 시작하다퍼블리셔, 프론트엔드개발을 시작하다
퍼블리셔, 프론트엔드개발을 시작하다정석 양
 

Similar to Pro android performance optimization 20171213 (20)

게임 데이터 분석을 위한 Data Lake 구축과 Machine Learning 을 활용한 분석 Hands on Lab (안효빈 솔루션즈 ...
게임 데이터 분석을 위한 Data Lake 구축과 Machine Learning 을 활용한 분석 Hands on Lab (안효빈 솔루션즈 ...게임 데이터 분석을 위한 Data Lake 구축과 Machine Learning 을 활용한 분석 Hands on Lab (안효빈 솔루션즈 ...
게임 데이터 분석을 위한 Data Lake 구축과 Machine Learning 을 활용한 분석 Hands on Lab (안효빈 솔루션즈 ...
 
Mongo db 최범균
Mongo db 최범균Mongo db 최범균
Mongo db 최범균
 
[NDC2015] 언제 어디서나 프로파일링 가능한 코드네임 JYP 작성기 - 라이브 게임 배포 후에도 프로파일링 하기
[NDC2015] 언제 어디서나 프로파일링 가능한 코드네임 JYP 작성기 - 라이브 게임 배포 후에도 프로파일링 하기[NDC2015] 언제 어디서나 프로파일링 가능한 코드네임 JYP 작성기 - 라이브 게임 배포 후에도 프로파일링 하기
[NDC2015] 언제 어디서나 프로파일링 가능한 코드네임 JYP 작성기 - 라이브 게임 배포 후에도 프로파일링 하기
 
Amazon Rekognition을 이용하여 인공지능 안면 인식 키오스크 만들기 - 강정희 (AWS 솔루션즈 아키텍트)
Amazon Rekognition을 이용하여 인공지능 안면 인식 키오스크 만들기 - 강정희 (AWS 솔루션즈 아키텍트)Amazon Rekognition을 이용하여 인공지능 안면 인식 키오스크 만들기 - 강정희 (AWS 솔루션즈 아키텍트)
Amazon Rekognition을 이용하여 인공지능 안면 인식 키오스크 만들기 - 강정희 (AWS 솔루션즈 아키텍트)
 
권기훈_포트폴리오
권기훈_포트폴리오권기훈_포트폴리오
권기훈_포트폴리오
 
안드로이드스터디 1
안드로이드스터디 1안드로이드스터디 1
안드로이드스터디 1
 
딥러닝 세계에 입문하기 위반 분투
딥러닝 세계에 입문하기 위반 분투딥러닝 세계에 입문하기 위반 분투
딥러닝 세계에 입문하기 위반 분투
 
배워봅시다 머신러닝 with TensorFlow
배워봅시다 머신러닝 with TensorFlow배워봅시다 머신러닝 with TensorFlow
배워봅시다 머신러닝 with TensorFlow
 
[2017 AWS Startup Day] 스타트업이 인공지능을 만날 때 : 딥러닝 활용사례와 아키텍쳐
[2017 AWS Startup Day] 스타트업이 인공지능을 만날 때 : 딥러닝 활용사례와 아키텍쳐[2017 AWS Startup Day] 스타트업이 인공지능을 만날 때 : 딥러닝 활용사례와 아키텍쳐
[2017 AWS Startup Day] 스타트업이 인공지능을 만날 때 : 딥러닝 활용사례와 아키텍쳐
 
AWS기반 서버리스 데이터레이크 구축하기 - 김진웅 (SK C&C) :: AWS Community Day 2020
AWS기반 서버리스 데이터레이크 구축하기 - 김진웅 (SK C&C) :: AWS Community Day 2020 AWS기반 서버리스 데이터레이크 구축하기 - 김진웅 (SK C&C) :: AWS Community Day 2020
AWS기반 서버리스 데이터레이크 구축하기 - 김진웅 (SK C&C) :: AWS Community Day 2020
 
AWS기반 서버리스 데이터레이크 구축하기 - 김진웅 (SK C&C) :: AWS Community Day 2020
AWS기반 서버리스 데이터레이크 구축하기 - 김진웅 (SK C&C) :: AWS Community Day 2020AWS기반 서버리스 데이터레이크 구축하기 - 김진웅 (SK C&C) :: AWS Community Day 2020
AWS기반 서버리스 데이터레이크 구축하기 - 김진웅 (SK C&C) :: AWS Community Day 2020
 
Software Architect day - 웹 프레임워크 종결 - metaworks3
Software Architect day - 웹 프레임워크 종결 -  metaworks3Software Architect day - 웹 프레임워크 종결 -  metaworks3
Software Architect day - 웹 프레임워크 종결 - metaworks3
 
Tiny ml study 20201031
Tiny ml study 20201031Tiny ml study 20201031
Tiny ml study 20201031
 
Openface
OpenfaceOpenface
Openface
 
[E-commerce & Retail Day] 인공지능서비스 활용방안
[E-commerce & Retail Day] 인공지능서비스 활용방안[E-commerce & Retail Day] 인공지능서비스 활용방안
[E-commerce & Retail Day] 인공지능서비스 활용방안
 
모바일을 위한 (AWS) 클라우드 기술 동향
모바일을 위한 (AWS) 클라우드 기술 동향 모바일을 위한 (AWS) 클라우드 기술 동향
모바일을 위한 (AWS) 클라우드 기술 동향
 
Real-time Big Data Analytics Practice with Unstructured Data
Real-time Big Data Analytics Practice with Unstructured DataReal-time Big Data Analytics Practice with Unstructured Data
Real-time Big Data Analytics Practice with Unstructured Data
 
Hacosa js study 4주차
Hacosa js study 4주차Hacosa js study 4주차
Hacosa js study 4주차
 
About Visual C++ 10
About  Visual C++ 10About  Visual C++ 10
About Visual C++ 10
 
퍼블리셔, 프론트엔드개발을 시작하다
퍼블리셔, 프론트엔드개발을 시작하다퍼블리셔, 프론트엔드개발을 시작하다
퍼블리셔, 프론트엔드개발을 시작하다
 

Pro android performance optimization 20171213

  • 1. Pro Android Performance Optimization Jun Chang Wook
  • 2. TITLE : Android 개발 최초 고려사항
  • 3. TITLE : Android 최적화 소스 개발 시 해야 될 일
  • 4. TITLE : 재귀적 호출 방법을 순환 호출 방법으로 변경 REASON
  • 5. TITLE : Android SparseArray 사용 REASON
  • 7. TITLE :+ 연산자 System.out.println(“y의 값은: ” + y); Log.e(“”, A+B+C+D+E+F+G+H+I+J+K+L+M+N); + 하는 String 의 갯수가 늘어나면 늘어날수록 GC 대상 object 수도 함께 늘어나고 그만큼 memory 할당도 추가로 된다. REASON
  • 8. TITLE : DB compileStatement boilerplate String sql = "INSERT INTO tip (tip_creator, symbol, target_price, reason) VALUES (?, ?, ?, ?)"; StockDatabase dbHelper = new StockDatabase(this.getApplicationContext()); SQLiteDatabase db = dbHelper.openDatabase(); SQLiteStatement stmt = db.compileStatement(sql); stmt.bindString(1, "USERNAME"); stmt.bindString(2, symbol); stmt.bindDouble(3, targetPrice); stmt.bindString(4, reason); stmt.execute(); stmt.close(); db.close();
  • 10. TITLE : Broadcast Receiver (Battery) enableBatteryReceiver(true); enableBatteryReceiver(false);
  • 11. TITLE : wakelock (Battery)
  • 12. TITLE : wakelock 해제(Battery) Layout <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:keepScreenOn="true"> Source getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
  • 14. TITLE : Memory 관리 REFERENCE OBJECT 1. Strong Reference Strong Reference는 new를 이용해 생성된 객체는 GC에서 무조건 제외되기 때문에 메모리 누수(Memory Leak)을 방지하기 위해서는 이 참조를 주의해서 보아야 합니다. 이 참조를 지워주지 않으면 GC에 의해 수거되지 않고 남아 있기 때문에 메모리 누수를 유발할 수 있습니다. 2. Soft Reference SoftReference는 다음과 같이 객체에 Reference를 넘겨줌으로서 생성할 수 있습니다. SoftReference object = new SoftReference(new Object()); 이 참조는 메모리가 충분하다면 GC에 의해서 수거되지 않고, 메모리에 여유가 없다면 GC에 의해 수거됩니다. 3. Weak Reference WeakReference는 SoftReference와 유사하지만 GC가 발생되기 전까지는 참조를 유지하고 GC가 발생하면 무조건 회수된다는 점에서 차이가 있습니다. 이는 유용하게 쓰일 수 있는데, 짧은 시간, 자주 쓰일 수 있는 객체를 이용할 때 유용하게 사용될 수 있습니다.
  • 15. TITLE : Memory 관리 class BitmapWorkerTask extends AsyncTask { private final WeakReference imageViewReference; private int data = 0; public BitmapWorkerTask(ImageView imageView){ imageViewReference = new WeakReference(imageView); } @Override protected Bitmap doInBackground( Integer... params){ data = param[0]; return decodeSampledBitmapFromResource( getResources(), data, 100, 100); } @Override protected void onPostExecute( Bitmap bitmap){ if( imageViewReference != null && bitmap != null){ final ImageViewReference imageView = imageViewReference.get(); if( imageView != null){ imageView.setImageBitmap( bitmap); } } } }
  • 16. TITLE : Memory 관리 LruCache는 LinkedHashMap을 사용하여 최근에 사용된 object의 strong reference를 보관하고 있다가 정 해진 사이즈를 넘어가게 되면 가장 최근에 사용되지 않은 놈부터 쫓아내는 LRU 알고리즘을 사용하는 메모리 캐시다 Android.util.LruCache<K, V> LruCache의 캐시사이즈를 정하기 위해서는 다음 요소들을 고려해야 한다. 1. 우리 앱에서 앞으로 메모리를 얼마나 써야 되는가 ?. 2. 얼마나 많은 이미지들이 한 화면에 보일 것인가? 3. 얼마나 많은 이미지들이 다음에 보여주기 위해 준비되어야 하는가? 4. 화면 해상도가 어떻게 되는가? 5. 각 이미지 마다 메모리를 얼마나 차지하는가? 6. 이미지는 얼마나 자주 액세스 되는가? 위에 내용을 고려해서 정해야 하며 어느정도 캐시사이즈가 적당한지 공식은 없고 앱의 메모리 사용량을 측정해보면서 적당히 정해야 한다. 당연한 말이겠지만 너무 사이즈를 작게 하면 괜히 오버헤드만 발생하게 되고 사이즈를 너무 크게 했다가 OutOfMemory Exception을 보게 될 거다. 많은 양의 저해상도 이미지를 미리 보여주고 백그라운드로 고해상도 이미지를 로드 하는 방법이 좋을 수도 있다.
  • 17. TITLE : Memory 관리 Android.util.LruCache<K, V> private LruCache mMemoryCache; @Override protected void onCreate(Bundle savedInstanceState) { ... // Get memory class of this device, exceeding this amount will throw an // OutOfMemory exception. final int memClass = ((ActivityManager) context.getSystemService( Context.ACTIVITY_SERVICE)).getMemoryClass(); // Use 1/8th of the available memory for this memory cache. final int cacheSize = 1024 * 1024 * memClass / 8; mMemoryCache = new LruCache(cacheSize) { @Override protected int sizeOf(String key, Bitmap bitmap) { // The cache size will be measured in bytes rather than number of items. return bitmap.getByteCount(); } }; ... } public void addBitmapToMemoryCache(String key, Bitmap bitmap) { if (getBitmapFromMemCache(key) == null) { mMemoryCache.put(key, bitmap); } } public Bitmap getBitmapFromMemCache(String key) { return mMemoryCache.get(key); }
  • 18. Reference 자료 출처: http://itmining.tistory.com/10 [IT 마이닝] https://github.com/apress/pro-android-apps-perf-optimization 안드로이드 앱 성능 최적화 출판사 프리렉 출처: http://dpug.tistory.com/33#.Wi5rJ0pl-Hs [퍼그의 전초기지] 출처: http://aroundck.tistory.com/11 [돼지왕 왕돼지 놀이터] https://www.codota.com/android/methods/android.database.sqlite.SQLiteDatabase/compileStatement 출처: http://caliou.tistory.com/122 [미녀개발자님의 블로그] https://www.androidpub.com/2426245