Android 11에서 더 이상 사용되지 않는 Android AsyncTask API 대안은 무엇입니까?


21

편집 :이 질문은 중복되지 않습니다

  1. 며칠 전 지원 중단에 대한 AOSP 커밋이 완료되었습니다.
  2. 다른 질문은 AsyncTask보다 AsyncTaskLoader를 사용하는 것입니다.


Google은 Android 11에서 Android AsyncTask API를 더 이상 사용하지 않으며 java.util.concurrent대신 사용할 것을 제안합니다 . 여기서 커밋을 확인할 수 있습니다

 *
 * @deprecated Use the standard <code>java.util.concurrent</code> or
 *   <a href="https://developer.android.com/topic/libraries/architecture/coroutines">
 *   Kotlin concurrency utilities</a> instead.
 */
@Deprecated
public abstract class AsyncTask<Params, Progress, Result> {

Android에서 비동기 작업으로 오래된 코드베이스를 유지 관리하는 경우 나중에 변경해야 할 것입니다. 내 질문은를 사용하여 아래에 표시된 코드 스 니펫을 올바르게 대체해야한다는 것 java.util.concurrent입니다. 활동의 정적 내부 클래스입니다. 나는 함께 작동하는 것을 찾고 있습니다minSdkVersion 16

private static class LongRunningTask extends AsyncTask<String, Void, MyPojo> {
        private static final String TAG = MyActivity.LongRunningTask.class.getSimpleName();
        private WeakReference<MyActivity> activityReference;

        LongRunningTask(MyActivity context) {
            activityReference = new WeakReference<>(context);
        }

        @Override
        protected MyPojo doInBackground(String... params) {
            // Some long running task

        }

        @Override
        protected void onPostExecute(MyPojo data) {

            MyActivity activity = activityReference.get();
            activity.progressBar.setVisibility(View.GONE);
            populateData(activity, data) ;
        }     


    }

5
'더 이상 사용되지 않음'은 Google이 다른 것으로 이동하도록 권장하고 있음을 의미합니다. 클래스가 곧 제거 될 것이라는 의미는 아닙니다. 특히 AsyncTask하위 호환성을 유지하지 않으면 제거 할 수 없습니다.
CommonsWare


2
@ Style-7은 그렇지 않습니다.
EpicPandaForce

"정적 내부 클래스"와 같은 것은 없습니다. 정적 중첩 클래스를 의미합니다.
beroal

답변:


22
private WeakReference<MyActivity> activityReference;

적절한 해법이 아니고 항상 해킹 이었기 때문에WeakReference<Context> 더 이상 사용되지 않는다는 좋은 의견 .

이제 사람들은 코드를 살균 할 수있는 기회를 갖게 될 것입니다.


AsyncTask<String, Void, MyPojo> 

이 코드를 기반으로 Progress실제로 필요하지 않으며 String입력 + MyPojo출력이 있습니다.

실제로 AsyncTask를 사용하지 않고도 쉽게 달성 할 수 있습니다.

public class TaskRunner {
    private final Executor executor = Executors.newSingleThreadExecutor(); // change according to your requirements
    private final Handler handler = new Handler(Looper.getMainLooper());

    public interface Callback<R> {
        void onComplete(R result);
    }

    public <R> void executeAsync(Callable<R> callable, Callback<R> callback) {
        executor.execute(() -> {
            final R result = callable.call();
            handler.post(() -> {
                callback.onComplete(result);
            });
        });
    }
}

문자열을 전달하는 방법? 이렇게 :

class LongRunningTask implements Callable<MyPojo> {
    private final String input;

    public LongRunningTask(String input) {
        this.input = input;
    }

    @Override
    public MyPojo call() {
        // Some long running task
        return myPojo;
    }
}

// in ViewModel
taskRunner.executeAsync(new LongRunningTask(input), (data) -> {
    // MyActivity activity = activityReference.get();
    // activity.progressBar.setVisibility(View.GONE);
    // populateData(activity, data) ;

    loadingLiveData.setValue(false);
    dataLiveData.setValue(data);
});

// in Activity
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.main_activity);

    viewModel = ViewModelProviders.of(this).get(MyViewModel.class);
    viewModel.loadingLiveData.observe(this, (loading) -> {
        if(loading) {
            progressBar.setVisibility(View.VISIBLE);
        } else {
            progressBar.setVisibility(View.GONE);
        }
    });

    viewModel.dataLiveData.observe(this, (data) -> {
        populateData(data);
    }); 
}

이 예에서는 DB 쓰기 (또는 직렬화 된 네트워크 요청)에 적합한 단일 스레드 풀을 사용했지만 DB 읽기 또는 여러 요청에 대해 원하는 경우 다음 Executor 구성을 고려할 수 있습니다.

private static final Executor THREAD_POOL_EXECUTOR =
        new ThreadPoolExecutor(5, 128, 1,
                TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());

에 오류가 발생했습니다 executor.post. 방법을 해결할 수 없습니다
크리스 B

@KrisB는 분명히 execute()대신에 호출 됩니다post()
EpicPandaForce

Context이것 으로 통과해도되는지 알고 있습니까? 나는 지나가는 것을 알고 Context로하는 것은 AsyncTask그것의 문제 중 하나였다.
Kris B

Android에서 비동기 적으로 수행하는 것과 마찬가지로 ViewModel, 유지 된 조각, 싱글 톤 또는 그 밖의 다른 것에서도 여전히 이것을 실행해야합니다.
EpicPandaForce

1
newSingleThreadExecutor쓰기에는 더 좋지만 THREAD_POOL_EXECUTOR데이터베이스 읽기에는 게시물 끝에 반드시 사용해야합니다 .
EpicPandaForce 1

3

Java의 동시성 프레임 워크 또는 Kotlin Coroutines를 사용하는 것이 좋습니다. 그러나 Rxjava는 훨씬 더 많은 유연성과 기능을 갖기 때문에 Java 동시성은 매우 인기를 얻었습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.