2014-05-21 2 views
1

비동기 작업을위한 일반 아키텍처를 만드는 방법에 대한 많은 내용을 읽었습니다. 하지만 여전히 문제가 있습니다.다중 http 요청을위한 아키텍처

대부분의 웹 예제는 AsyncTask의 도움으로 웹 서비스에 대한 연결을 보여줍니다. 우리는이 간단한 아키텍처를 사용하여 활동을 재현 할 때 문제가 발생합니다. 즉, 장치가 가로 방향에서 세로 방향으로 또는 그 반대로 방향을 바꿀 때입니다. 작업이 시작되었지만 사용자가 다시 누르면 현재 AsyncTask에 대한 모든 정보가 손실되었을 때 문제가 발생합니다.

일부 요청을 단순히 실행할 수 있고 작업이 끝난 후 호출되는 활동에 대한 콜백을 가질 수있는 아키텍처를 만들고 싶습니다. 백그라운드 작업에 서비스를 사용하고 조작을 처리하려면 ThreadExecutor을 사용할 계획입니다.

여기는 내가 발견 한 스레드 및 백그라운드 작업에 대한 가장 유용한 링크입니다. http://www.slideshare.net/andersgoransson/efficient-android-threading

이제이 방법을 구현하는 데 유용한 코드 예제를 알려주시겠습니까? 어떤 주석 (튜토리얼 MB가 아니라 Github에있는 프로젝트가 아님)이있을 수 있지만 코드를 사용하여 이것이 어떻게 구현되는지보십시오.

+1

동일한 접근 방식을 사용하는 통신 프레임 워크를 개발하는 당사는 자체적 인 작업 관리를 수행했습니다. ExecutorService를 사용하여 실행합니다. 또한 몇 가지 실행 모드를 만들었습니다. 일부 작업은 순서대로 (예 : 동일한 원격 호스트에 여러 요청이있을 때) 또는 병렬로 실행해야합니다. –

+0

@ АндрейМосквичёв 우리와 공유 할 수있는 몇 가지 소스 코드 예제가 있습니까? – Anatol

+0

출처는 독점적입니다. 우리가 만든 것에 대한 간단한 설명을 드릴 수 있습니다. –

답변

1

우리 회사는 우리 자신의 비동기 작업 관리를 만든 모바일 웹 데스크톱 통신 프레임 워크를 개발하고 있습니다.

프레임 워크는 원격 장치와 작동하며 로컬 장치와 원격 장치 간의 각 트랜잭션은 트랜잭션 (AsyncTask의 확장 아날로그)에서 수행됩니다.

TransactionManager 클래스는 모든 트랜잭션을 보유하고 트랜잭션의 실행을 담당합니다. 단일 스레드 및 캐시 된 스레드 풀 ExecutorService가 있습니다. 트랜잭션이 명시 적으로 표시되면 병렬로 실행될 수 있습니다. 트랜잭션은 캐시 된 스레드 풀 (다중 스레드 모드)에서 실행되며, 지나치게 단일 스레드 실행 프로그램에서 실행됩니다. 모든 트랜잭션이 다중 스레드로 실행될 수있는 것은 아니므로 멀티 스레드 모드에서 실행되는 경우 (예 : 로컬 또는 원격 장치의 상태를 변경하는 여러 트랜잭션이있는 경우) 부작용이 발생할 수 있기 때문에이 작업이 수행됩니다.

어떻게 단일 cached-를 만들거나 고정 ExecutorService를 여기에서 찾을 수 있습니다 Executors

TransactionManager를 자체 서비스에 있습니다. 여기에 설명 된대로 로컬 바인딩을 통해 다른 모든 응용 프로그램의 구성 요소에 연결된 서비스 Bound Services

각 트랜잭션에는 고유 식별자, 참여 장치, 메시지 진행 및 상태. 상태는 NotStarted, Started, Error, Finished 일 수 있습니다. 메시지가 UI에 표시됩니다. 현재 수행되는 내용입니다. 고유 식별자 (uid)는 uid를 의도적으로 전송하여 트랜잭션을 찾거나 다른 트랜잭션에 트랜잭션 정보를 보내는 데 사용됩니다. - AsyncTask를의 doInBackground 방법의 아날로그

protected void onRestoreInstanceState(Bundle savedInstanceState) { 
    super.onRestoreInstanceState(savedInstanceState); 

      // transaction manager holds all transactions 
    TransactionManager transactionManager = commService.getTransactionManager(); 

    String lsTransactionId = savedInstanceState.getString(LS_TRANSACTION_ID); 
    if (lsTransactionId != null) { 
     lsTransaction = (OutgoingTransaction<FileItem[]>) transactionManager.getTransactionById(lsTransactionId); 
     // update UI according to transaction state 
    } 
} 

@Override 
protected void onSaveInstanceState(Bundle outState) { 
    super.onSaveInstanceState(outState); 

      // if we have runnng transaction - store it's id to bundle 
    if (lsTransaction != null) { 
     outState.putString(LS_TRANSACTION_ID, lsTransaction.getId()); 
    } 
} 

트랜잭션 클래스가 추상 메소드가 실제 작업 (다운로드 또는 데이터 등을 업로드) 할 수행

우리는 다음과 같은 화면이 문제를 회전 해결했다.

트랜잭션이 이벤트의 수신 청취자가 : 여기

public interface TransactionListener<T> { 
/** 
* Called when transaction is started. 
*/ 
void started(); 

/** 
* Called when transaction message is posted by Transaction.setMessage call. 
* @param message message 
*/ 
void message(String message); 

/** 
* Called when transaction is finished. 
* @param result transaction result 
*/ 
void finished(T result); 

/** 
* Called when transaction is cancelled. 
*/ 
void cancelled(); 

/** 
* Called when transaction error is occurred. 
* @param thr throwable indicating an error 
*/ 
void error(Throwable thr); 

/** 
* Called on transaction progress. 
* @param value progress value 
* @param total progress total 
*/ 
void progress(long value, long total); 
} 

그리고 다른 일 - 리스너 메서드는 UI 스레드에서 실행할 수 있도록하기를, 우리는 위의 방법을 실행하기 위해 Handler.post를 사용하는 헬퍼 클래스 AndroidTransactionListener가 만든 에 UI 스레드. Handler에 관해서는 여기에서 읽을 수 있습니다 : Handler

+0

응답 해 주셔서 감사합니다. 어쩌면 나중에 오랜 기간의 작업을 사용하여 올바른 프레임 워크를 작성하려고합니다. 이제는 Robospice를 사용하기로 결정했습니다. 그 이유는 캐싱 요청, 상자의 훌륭한 도구 때문입니다. – Anatol

0

발리 라이브러리는 원하는대로 할 수 있습니다. 자신의 라이브러리가 필요하다면 소스도 있습니다.

0

저는 이것을 위해 Robospice를 사용했습니다. 본질적으로 onResume()에 서비스 수준에서 연결하는 리스너가 있습니다. 작업을 해고하면 작업이 수행됩니다. 설치하는 데는 상당한 양의 작업이 필요하지만 수동 스레딩의 산보다 더 쉬웠습니다.

잘 정의 된 응답이있는 경우 캐싱도 지원됩니다.

관련 문제