728x90

비동기 처리를 하기 위해서는 별도의 Thread 를 생성하여 public void run()  메소드를 구현하면 되지만
안드로이드에서는 직접 Thread 를 생성하기 보다는 AsyncTask 를 사용하길 권장한다.

AsyncTask 는 execute( Runnable) 메소드도 제공하기 때문에 별도의 스레드 작업을 할때도 사용할 수 있다.

AsyncTask.execute(new Runnable() {
    @Override
    public void run() {
        try {
            getJson(Value.IPADDRESS + "/MyTask.php", params,context);
        } catch (Exception e) {
            new String("Exception: " + e.getMessage());
        }
    }
});


위 코드에서 context 가 들어간 이유는 public class Broadcast_Receiver extends BroadcastReceiver 에서 처리하는 코드이기 때문이다.

일반적인 AsyncTask 를 사용해서 처리하려고 하는데 코드 실행순서가 순차적으로 실행되지 않는 현상이 있었다.

아래 코드내에서는 순차적으로 실행되는데 PostExecute(String result) 에서 처리할 코드가 제대로 먹히지 않았다.

내가 아직 기본기가 부족해서 놓치는 부분이 있어서 인거 같다. (일반 AsyncTask  : http://link2me.tistory.com/1031)


서버에서 결과를 받아다가 처리한 이후에 코드가 실행될 줄 알았는데 비동기식이라 그런지 다음 코드가 먼저 실행되어 버리면서 전혀 기대하지 않았던 결과가 나왔다.

그래서 검색해서 찾아낸 코드가 AsyncTask.execute(new Runnable() 였고, 이 코드를 활용하여 원하는 결과를 얻을 수가 있었다.


@Override
public void onReceive(Context context, Intent intent) {
    // 네트워크 연결 체크
    NetworkChk(context, intent);

    // 잠든 화면 깨우기
    WakeLock(context, intent);
    
    // 전화 수신 체크
    CallReceivedChk(context, intent);
}

private void CallReceivedChk(final Context context, Intent intent) {

    if (state.equals(TelephonyManager.EXTRA_STATE_RINGING)) {

        AsyncTask.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    getJson(Value.IPADDRESS + "/MyTask.php",params,context);
                } catch (Exception e) {
                    new String("Exception: " + e.getMessage());
                }
            }
        });

}


이 코드가 메모리 문제까지 완벽하게 처리해주는지 여부는 아직 모른다.

병렬처리를 하는게 맞을 거 같아서 코드를 AsyncTask.THREAD_POOL_EXECUTOR.execute(new Runnable() 로 수정 적용했다.

AsyncTask.THREAD_POOL_EXECUTOR.execute(new Runnable() {
    @Override
    public void run() {
       
    }
});


충분한 테스트 이후에 문제가 없다면 결과를 다시 기록해두련다.



AsyncTask가 처음 도입되었을때는 순차적으로 하나의 백그라운드 쓰레드를 실행하였으나, DONUT(1.6버전)부터는 여러개의 태스크를 병렬적으로 처리하도록 변경이 되었고, 다시 HONEYCOMB(3.0버전)부터는 하나의 쓰레드만 실행하게끔 돌아왔다. 그리고 THREAD_POOL_EXECUTOR를 사용한 executeOnExecutor(Executor, Params...) 로 쓰레드를 병렬적으로 실행시킬수 있게 했다.

if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.HONEYCOMB) {
  myTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} else {
  myTask.execute();
}

AsyncTask.execute(new Runnable() {
    @Override
    public void run() {
       
    }
});

허니콤의 3.2버전에서는 AsyncTask의 쓰레드는 순차적으로 실행되므로 이전 태스크가 종료되기를 기다려야 한다.
그러므로 대기하지 않고 바로 실행시켜주려면 별도의 스레드에서 실행해야한다.
멀티 쓰레드로 Concurrent하게 데이터를 가져오거나 동작하게 하기 위해서는, 아래와 같이 AsyncTask를 실행할 때, AsyncTask.THREAD_POOL_EXECUTOR 스케줄러를 지정해야 한다.
new MyAsyncTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, “”);

AsyncTask.THREAD_POOL_EXECUTOR.execute(new Runnable() {
    @Override
    public void run() {
       
    }
});


참고하면 도움이 될 사이트

http://www.programing-style.com/android/android-api/android-asynctask-order-execute/

블로그 이미지

Link2Me

,