[android] AsyncTask를 여러 번 실행하십시오.



Answers

ASyncTask의 화재 및 잊어 버린 인스턴스에 대한 이유는 Steve Prentice의 대답에 자세히 설명되어 있습니다. 그러나 ASyncTask를 몇 번이나 실행하도록 제한되어 있지만 스레드가 실행되는 동안 마음껏 자유롭게 할 수 있습니다. .

실행 코드를 doInBackground () 내의 루프 안에 넣고 동시 잠금을 사용하여 각 실행을 트리거하십시오. publishProgress () / onProgressUpdate ()를 사용하여 결과를 검색 할 수 있습니다.

예:

class GetDataFromServerTask extends AsyncTask<Input, Result, Void> {

    private final ReentrantLock lock = new ReentrantLock();
    private final Condition tryAgain = lock.newCondition();
    private volatile boolean finished = false;

    @Override
    protected Void doInBackground(Input... params) {

        lock.lockInterruptibly();

        do { 
            // This is the bulk of our task, request the data, and put in "result"
            Result result = ....

            // Return it to the activity thread using publishProgress()
            publishProgress(result);

            // At the end, we acquire a lock that will delay
            // the next execution until runAgain() is called..
            tryAgain.await();

        } while(!finished);

        lock.unlock();
    }

    @Override
    protected void onProgressUpdate(Result... result) 
    {
        // Treat this like onPostExecute(), do something with result

        // This is an example...
        if (result != whatWeWant && userWantsToTryAgain()) {
            runAgain();
        }
    }

    public void runAgain() {
        // Call this to request data from the server again
        tryAgain.signal();
    }

    public void terminateTask() {
        // The task will only finish when we call this method
        finished = true;
        lock.unlock();
    }

    @Override
    protected void onCancelled() {
        // Make sure we clean up if the task is killed
        terminateTask();
    }
}

물론 이것은 ASyncTask의 전통적인 사용법보다 약간 더 복잡하며 실제 진행보고를 위해 publishProgress () 를 사용하지 않습니다 . 그러나 메모리가 걱정된다면이 접근 방식은 런타임시 힙에 하나의 ASyncTask 만 남도록 보장합니다.

Question

내 Activity에서는 AsyncTask와 AsyncTask의 인스턴스 인 매개 변수에서 확장되는 클래스를 사용합니다. mInstanceOfAT.execute("") 호출하면 모든 것이 잘됩니다. 하지만 AsyncTask (네트워크 작업이 작동하지 않는 경우)를 다시 호출하는 업데이트 버튼을 누르면 응용 프로그램이 다운됩니다. 원인은 다음과 같은 예외가 나타납니다.

작업을 실행할 수 없습니다 : 작업이 이미 실행되었습니다 (작업은 한 번만 실행될 수 있음).

Asyctask의 인스턴스에 대해 cancel (true)을 호출하려고했지만 그 중 하나가 작동하지 않습니다. 지금까지 유일한 해결책은 Asyntask의 새로운 인스턴스를 만드는 것입니다. 그게 올바른 방법일까요?

감사.




나는 같은 문제가 있었다. 내 경우에는 내가 onCreate()onResume( )에서하고 싶은 작업이 있습니다. 그래서 내 Asynctask 정적, 그리고 그것에서 인스턴스를 얻을. 이제 우리에게는 여전히 같은 문제가 있습니다.

그래서 내가 onPostExecute ()에서 한 것은 이것입니다 :

instance = null;

내 인스턴스가 null이 아닌 정적 getInstance 메소드를 체크인했는지 확인합니다. 그렇지 않으면 내가 생성합니다.

if (instance == null){
    instance = new Task();
}
return instance;

postExecute의 메소드는 인스턴스를 비우고 다시 작성합니다. 물론 이것은 수업 외부에서 할 수 있습니다.




Related