private void jsonDataInsert(int startIndex,int endIndex) throws JSONException{

JSONObject obj=new JSONObject(jsonText);
JSONArray items=obj.getJSONArray("recent");
int numOfItem=items.length();
Drawable d_thumb=null;

BitmapFactory.Options options=new BitmapFactory.Options();

options.inPurgeable=true;
options.inSampleSize=4;

// items의 모든 데이터 순회
for(int i=startIndex;i<numOfItem;i++){
    if(endIndex<numOfItem&&i==endIndex){ break; }

 

JSONObject jsonString=items.getJSONObject(i);
try{
    d_thumb=LoadImageFromWeb(jsonString.getString("src"),options);
}catch(Exception e){}
    // 각 항목의 author의 title 키의 값을 하나의 문자열로 만들어서 data에 추가
    data.add(new Item(d_thumb,jsonString.getString("subject")));
    handler.sendEmptyMessage(0);
    //d_thumb.setCallback(null);

}

}

 

private Drawable LoadImageFromWeb(String url,BitmapFactory.Options options) throws MalformedURLException,IOException{

InputStream is=(InputStream)new URL(url).getContent();

Drawable d=Drawable.createFromResourceStream(getResources(),null,is,"src name",options);

return d;

}

 

BitmapFactory.Option으로 inPurgeable, inSampleSize을 셋팅 합니다.

options.inPurgeable=true; 시스템이 메모리에서 반환하기를 원할때 메모리에서 제거된다.

options.inSampleSize=4; 1/4로 이미지를 가져오기때문에 outOfMemory문제가 해결된다.

 

이외에도 여러가지 시나리오에 따라 이미지리소스에 대한 뒤처리라던지 깔끔하게 해주어야 한다.

 

일반적으로 알려진 API Level 11부터(허니컴)는 Manifest에 application태그에 largeHeap="true" 옵션추가로 해결할 수 있는데 큰이미지를 받았을 경우 처리는 가능하지만 앱동작이 느려지는 단점이 있다.

이미지의 퀄리티가 많이 떨어지지않는 내에서 줄여서 가져와야 앱동작이 더 수월할것이다.

 

 

위의 상황도 아직 시나리오에 따른 코드를 더 정리하면 좋겠지만, Bad Case의 경우 저 정도로도 나은 성능이 나온다는 것을 확인할 수 있다.

Posted by duehd88
,

AsyncTask에서 언급했었는데 안드로이드는 Single Thread기반의 GUI모델이다.

app에는 항상 MainThread 하나가 돌고 있고 이 MainThread만이 UI를 건들일 수 있다. 그래서 UI Thread라고도 한다.

문제는 무거운 작업을 background Thread에 넘겨서 작업한뒤 UI를 그리려고 해도 SingleThread기반인 탓에 UI Thread가 아니면 그릴 수 가 없다.

그래서 이럴때 사용하는 nice한 방법 여러가지를 소개하고자 한다.

(만약 무거운 작업을 MainThread에서 처리하려고 한다면 코드가 Block되는 일로 인해 치명적인 에러로 분류되는 ANR(Application Not Responding)이 발생할 가능성이 있다.)

 

1. Handler 이용. Thread간에 상호작용을 할때 가장 일반적으로 생각할 수 있는 방법이다.

2. UI Thread가 작업할때 메시지큐로 작업을 전달하는 방법(Looper등등...)

3. 안드로이드에서 제공해주는 AsyncTask 클래스. 굉장히 코드가 단순해지는 장점이 있으나, 문제는 없지만 효율성이 떨어지는 코드가 나오는 경우가 있다. 이를 보완한 다른 클래스를 안드로이드가 제공해준다.

3번에서 언급한거 처럼 안드로이드에서 제공해주는 다른 몇몇 클래스를 이용하여 처리할 수 있다.

 

이번 글에는 사용해본 몇가지 방법을 기록하고자 한다.

01. Handler.post방식

Handler handler=new Handler();

handler.post(new Runnable(){

public void run(){

...

}

});

 

02. Looper Handler

client라는 thread클래스

Handler SendHandler;

run(){

Looper.prepare();

SendHandler=new Handler(){

public void handleMessage(Message msg){
    ...

}//handleMessage end

};//SendHandler end

Looper.loop();

}

client라는 thread에 SendHandler에 메시지를 넣는다.

Message msg=Message.obtain(client.SendHandler,arg);
client.SendHandler.sendMessage(msg);

 

03. mainThread안에 handler를 만들어 놓고 다른쓰레드에서 메시지를 넣어주는 방법

참고로 덧붙여 설명하자면 mainthread는 기본적으로 looper를 가지고 있기 때문에 message queue와 연결되어있다. 하지만 위의 looper는 다른쓰레드와 message queue와 연결 시켜주는 역할을 한다.

 

04. runOnUiThread방식

activity.runOnUiThread(new Runnable(){

public void run(){

...

}

});

 

05. AsyncTask 검색하면 사용법잘나와있다.

 

참고로 UI를 그리는 것에 관여하는 클래스들중 따로 이런기법을 쓰지않고도 다른 thread에서 UI를 그려주기 위한 메서드들을 갖고 있는 것들이 있다.

postinvalidate등등...

 

각자 나이스한 case가 있다. 잘사용하자

Posted by duehd88
,

블루투스 흐름

1. 블루투스가 활성화 되어있는가? 비활성화되어있다면 활성화 시작

2. 블루투스가 활성화되면 다른 디바이스를 페어링하기위해 통신가능 장비 스캔시작

3. 블루투스 장비 페어링을 위해 로컬블루투스어댑터에 쿼리를 날린다.

4. RFCOMM 채널들을 설정한다.

5. SDP(Service Discoverry Protocol)을 통해 다른 디바이스와 연결한다.

6. 연결된 디바이스와 데이터를 주고 받는다.

7. 다중 연결자들을 관리한다.

블루투스 기본 API

모든 블루투스관련 API들은 android.bluetooth 패키지에 있다. 클래스와 인터페이스를 알아보면

▶ BluetoothAdapter : 로컬 블루투스 어댑터, 모든 블루투스 연동을 위한 entry-point가 된다. 얘를 이용해서 다른 디바이스들을 검색하고, 페어링된 장비들에 쿼리를 날리고 알고있는 MAC 주소를 이용해 블루투스 디바이스들을 인스턴스화 한다. 또 다른 디바이스로부터 recieve하기 위해 서버소켓도 생성한다.

▶ BluetoothDevice : 원격 블루투스 장비를 나타낸다. 여기서 제공되는 BluetoothSocket을 이용해 연결된 장비에게 요청 혹은 여러 상태 정보를 가져온다.

▶ BluetoothSocket : TCP 소켓과 유사한 블루투스 소켓에 대한 인터페이스를 나타내며 여기서 제공되는 InputStream과 OutputStream을 통해 다른 장비와 데이터를 교환한다.

▶ BluetoothServerSocket : TCP Server 소켓처럼 요청을 받아들이기 위한 서버를 열때 이용된다. 2개의 장비중 하나는 반드시 이 클래스를 이용하여 서버 소켓을 오픈해야한다. 연결을 accept할시 연결된 BluetoothSocket을 반환한다.

▶ BluetoothClass : 블루투스 디바이스의 특징과 기능들에 대한 기술서를 나타냅니다. 여기엔 디바이스의 major, minor 클래스와 제공하는 서비스들이 정의된 읽기 전용 property들이 설정되어 있습니다.

▶ BluetoothProfile : 블루투스 프로필을 나타내는 인터페이스입니다. 디바이스 간에 블루투스 통신을 하기 위한 무선 인터페이스 규약입니다. 예를들면 Hands-Free Profile같은...

▶ BluetoothHeadset : 모바일 환경에서 사용하는 블루투스 헤드셋을 지원하기 위해 제공됩니다. Headset과 Hands-Free Profile을 포함하고 있습니다.

▶ BluetoothA2dp : 하이 퀄리티 오디오가 블루투스 연결 상에서 하나의 장비에서 다른 장비로 스트리밍될 수 있도록 정의되어 있다. A2DP는 Advanced Audio Distribution Profile을 나타낸다.

▶ BluetoothProfile.ServiceListener : BluetoothProfile IPC 클라이언트들이 서비스(특정 프로필을 실행하고 있는 내부 서비스)로 연결되거나 연결 해제될 경우를 알아내기 위한 인터페이스입니다.

블루투스 권한 설정

 어플리케이션에서 블루투스 기능을 사용하려면 늘 그렇듯 Manifest에다가 권한(Permission)을 설정해주어야한다.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.android.BluetoothTest"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="11"
        android:targetSdkVersion="16" />

    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
    <uses-permission android:name="android.permission.BLUETOOTH" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:name="com.example.android.BluetoothTestActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name="com.example.android.DeviceListActivity"
            android:label="@string/app_name" />
    </application>

</manifest>

BLUETOOTH_ADMIN은 블루투스의 설정조작 및 페어링할 장비 검색에 대한 권한이고

BLUETOOTH는 연결, 연결수라그 데이터 교환등 통신에 관련된 부분에 대한 권한이다.

Posted by duehd88
,

R언어

Programing/R 2014. 5. 25. 00:30

R 언어

http://ko.wikipedia.org/wiki/R_%28%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D_%EC%96%B8%EC%96%B4%29

 위의 위키백과에 따르면 통계계산, 그래픽에 특화된 프로그래밍 언어이자 소프트웨어환경이라고 한다.

 

 무엇보다 오픈소스라는 점과 많은 소스들이 개발되어 배포되고 있어서 생산성 및 공부하기 참 좋은 언어라는 것!!!

세미나서 졸다가 흘려들은거라 기억은 잘안나지만 빅데이터에서 이용되기도 한다고 들었던거 같다. 물론 꼭 빅데이터만은 아니겟지만...

아무튼 세미나에서 졸다가 빅데이터 내용에서 잠깐 나온 R이란 언어!!! 틈틈히 공부해보려고 한다.

 

일단 깔자!!

http://www.r-project.org/ 에서 왼쪽에 다운로드패키지 해서 깔면 된다. 딱히 설정을 건들일 필요는 없었다.

위의 이미지는 R을 설치하고 Graphic환경으로 열었을 경우이다.

위의 이미지는 R을설치하고 command환경으로 열었을 경우이다.

 

 

그 다음으로 R studio를 깔자 IDE개발환경이다. R자체가 개발환경을 지원하지만 더 편하게 관리하고자 설치하는것 이라는거!!!

http://www.rstudio.com/ 얘도 마찬가지로 설정할게 딱히 없다.

R studio처음 설치하고 열면 이렇게 나온다.

 

Posted by duehd88
,

이 둘의 차이를 망각하는 경우가 있다.

 

둘다 String을 integer로 변환하여 사용하고자 할때 쓴다.

하지만 둘은 다르다.

 

parseInt는 integer를 반환한다.

valueOf는 integer 객체를 반환한다.

 

또 parseInt는 "-"가 같이 들어갈 경우 음수로 인식해준다.

valueOf는 음수를 인식하지 못한다. 또 내부적으로 parseInt를 사용한다.

 

간혹 사람들중 성능차이를 이야기하던데... 성능보다는 용도차이로 구분을 하는게 더 정확한거 같다.

Posted by duehd88
,

 * 이 테스트는 ADT22.6에서 ADT22.3으로 작업한 프로젝트를 불러와서 테스트 했습니다.

 

타이틀바(Title Bar) 제거

1. 일단 Manifest.xml파일을 이용한 방법이다.

<application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@android:style/Theme.NoTitleBar" >

 이렇게 android:theme="@android:style/Theme.NoTitleBar"를 하면 제거 된다.

2.Activity에 소스코드로 제거하기

getWindow() 메소드로 Window 클래스 객체를 생성한다. 그리고 requestFeature() 메소드를 통해 윈도우 확장 기능을 활성화하는 방법이다.

또 굳이 getWindow()하지 않아도 해당클래스 객체 자체의 윈도우특성을 이용할 수 있다.

 

//1. example

Window winObj=getWindow();

winObj.requestFeature(Window.FEATURE_NO_TITLE);

//2. example

this.requestWindowFeature(Window.FEATURE_NO_TITLE);

 

주의사항은 setContentView();를 호출하기전에 윈도우 셋팅을 끝내야 한다. 또 셋팅이 끝난 후 변경할 수 없다. 그리고 간혹 빨간줄 뜨면 제발 ctrl+shift+o 누르자

 

인디케이터바(Indicator Bar) 제거

1. 이 녀석도 일단 Mnifest.xml을 이용할 수 있다.

<application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@android:style/Theme.NoTitleBar.Fullscreen" >

 이렇게 android:theme="@android:style/Theme.NoTitleBar.Fullscreen"를 하면 타이틀바와 인디케이터가 함께 제거 된다.

2. Activity에서 소스코드로 제거하기

위의 example1에서 addFlags()로 레이아웃 관련된 플래그를 찾아 넣어 주엇다.

Window winObj=getWindow();
winObj.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);

---------------------------------------------------------------------------또는
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
    WindowManager.LayoutParams.FLAG_FULLSCREEN);

주의사항은 위와 같다.

 

 

 

 참고로 xml을 이용한 방법에서 application 태그에 해당 android:theme attribute를 넣으면 앱전체에 적용되고 Activity태그에 넣으면 해당 액티비티에만 적용된다.

뭔가 코드로 적용할때와 xml로 적용할때에 Layout에서 기술한 버튼이 조금 달라지는것을 경험 했다. xml로 테마를 건들일시 뭔가 초기화되는거 같다.

Posted by duehd88
,

 String과 StringBuffer와 StringBuilder는 모두 문자열 처리 Class이다. 

그렇다면 Why? 자바 설계자들은 문자열 처리 클래스를 저렇게 나누어 놨을까? 생각해보자

저 이름에서 보이듯이 뭔가 내부에서 처리 방법이라던가 경우에 따른 사용방법때문에 나누었을 거라는 생각을 대충 해볼 수 있다.

 

실제로 사람들은 초기에 배울때 String Class를 많이 사용한다. 그리고 좀 배우다 보면 StringBuffer와 StringBuilder라는 Class를 배우고 이 녀석들이 performance 더 좋다는 것만보고 전부 StringBuffer와 StringBuiler로만 처리하는 걸 많이 봤다. 이제 정확한 사용법을 위해 각각의 특징을 대충 알아보자.

 

mutable과 immutable pattern

우선 이 두 개념을 간단하게 보자. 공유 자원들은 사용시 thread safety(multi-thread safety)해야 올바른 결과를 보장할 수 있다. 그래서 immutable은 한번 만든 객체는 변경되지 않으며, 변경시에는 새로운 객체를 만든다. 이 말은 synchronized하지 않아도 thread safety하다는 뜻이다. mutable은 원본 자체를 수정해야하기 때문에 synchronized해야만 올바른 결과가 보장된다.

 

String Class

 이 녀석은 immutable한 클래스이다. 변경 불가능한 클래스라는 뜻이다. 하지만 안의 메소드(toLowerCase(), trim()... 등등)를 생각해보면 자칫 변경가능한 녀석이라고 생각할 수 있다. 하지만 실제론 안에서 원본 객체는 놔둔채 각메서드에서 새로운 객체를 만들어 기능을 처리한 후 반환한다. 즉, 원본은 변경되지 않는 것이다. 그래서 String 클래스는 객체를 새로 할당하는 시간 및 새로운 메모리사용 때문에 다른 문자열 클래스에 비해 좀 더 느리다고 생각될 수 있다.

 

StringBuffer Class

 이 녀석은 mutable하다. 그러니까 가지고 있는 원본을 수정할 수 있도록 만든 Class이다. 당연 thread safety하기 위한 synchronized과정이 있다. 이 synchronized과정에 있어서 단순한 참조를 할경우 String보다 bad performance를 보인다.

 

StringBuilder Class

 이 녀석 또한 mutable하다. StringBuffer와 동일한 기능을 갖고있는데 차이점이라고 한다면 thread safety하지 않다. 즉, synchronized 과정이 없다는 것 이다. 그래서 thread safety할 필요 없는 코드라면 stringBuffer가 아닌 StringBuilder를 써야 더 좋은 performance가 나온다.

 

 

 정리 하자면 하나의 문자열에 대해 다른 문자열이 자주 추가되는 경우에는 StringBuffer와 StringBuilder가 유리하지만, 이 외의 용도에서는 오히려 StringBuffer나 StringBuilder가 훨씬 메모리 자원 낭비될 수 있다. 그리고 항상 multi-thread safety해야 하는 경우 StringBuffer를 이용하고 아니라면 StringBuilder를 사용하자.

Posted by duehd88
,

AsyncTask 클래스

개발할 때 singleThread기반인 UI Thread(main Tread)에서 사용하는 공유자원에 바로 접근하면 thread safe하지 않기때문에 process가 죽는 경험을 할 수 있다. 이 때 여러 방법이 있는데

postInvalidate();, view.post(new Runnable(){/*...*/}); 등등... 다른 쓰레드에서 UI에 접근하는 어떠한 메서드를 불러주는 법이 있고,

Handler와 Thread를 이용한 방법이 있다. 하지만 Handler를 쓸때는 Thread를 UI Thread의 sub_thread?(일종의 UI Thread에 sw Interrupt로 동작한다고 생각하면 된다.)로 선언하고 사용해야 한다.

 

물론 위의 두방법은 누가 좋다고 할 수 가 없다. 왜냐하면 용도와 사용해야할 케이스가 다르다고 생각되어진다. 다른 쓰레드에서 쓰느냐 아니냐 쓴다면 어떤 용도로 쓰느냐 정도? 라고 보면 될 것 같다.

 

하여간 Handler와 Thread를 이용하는 방법이 아닌 AsyncTask라는 Class를 이용해보자! 이 녀석은 일단 UI 작업과 Background 작업을 하나의 Class에서 이용할 수 있게 지원한다. 즉, Handler를 이용하지않아도 Task객체로 각각의 주기마다 CallBack 메서드로 UI 수정 및 Background 작업을 할 수 있다는 뜻이다.

그리고 AsyncTask라는 Class를 이용함으로써 캡슐화하면 코드가 심플해지고 가독성이 높아진다. 당연 유지보수면에서도 좋다. 무엇보다 AsyncTask녀석은 내부에 Thread Pool이 있어 메모리에 부담을 주지 않도록 설계되어있다.

 

주의할점이 있다면 main Threa의 sub class이여야 한다. UI 작업할 때의 CallBack함수 때문인것 같다. 그리고 Activity이 종료시 별도의 지시가 없으면 AsyncTask가 남아있게 되는데 다시 이 앱을 실행 할때의 AyncTask와 충돌날 수 있다.(뭐 이 문제는 thread safe하지 않아서 나는 문제이다.) 해결법은  Activity 종료시 객체를 null로 넣어서 날려버리면 되지 않을까 싶다.

 

사용법은 android api부터 시작해서 여러 블로그에서 잘 다뤄지고 있다. 검색궈궈

 

http://developer.android.com/reference/android/os/AsyncTask.html - 안드로이드 API문서 AsyncTask Class

Posted by duehd88
,