Android:AsyncTask 的替代方案?

Android: Alternatives to AsyncTask?

我为我的应用程序制作了一个框架,用于所有对外部网络的调用 API。我把所有东西都放在 "Services" 中,例如:UserServiceMessageService 等。所以现在当我想调用网络方法时,我不能在 UI-Thread 中执行此操作我的 Activity 所以我做了一个 AsyncTask 一切都很好 =)

但现在我想要一些东西,比如将要执行的方法提供给 AsyncTask,这样我就不需要为我的网络框架的每个方法都写一个 AsyncTask。所以不要有这样的东西:

public class NetworkTask extends AsyncTask<UserService, Void, Void> {

    @Override
    protected Void doInBackground(UserService... params) {
        UserService userService = params[0];
        userService.getUser();
        return null;
    }
}

我想要更多 "abstract" 所以 AsyncTask 不需要知道 "getUser" 方法?但是我找不到任何关于如何做到这一点的想法......也许 AsyncTask 无论如何都不适合这个?

也许你可以使用像Retrofit这样的第三方库 如果您使用图像,我强烈建议 picasso

您可以使用 Volley 库,它在后台线程上工作,并在事情完成后将控制权交还给主线程。

请记住 Android 有线程和 AsyncTasks 的限制。

您可以使用 2 个库来完成 AsyncTasks 的相同工作:

  1. 截击 -> http://www.androidhive.info/2014/05/android-working-with-volley-library-1/

  2. LoopJ -> http://loopj.com/android-async-http/

更新:

我真的很推荐Retrofit 2。 http://square.github.io/retrofit/

有很多 AsyncTask 替代品:

https://android-arsenal.com/tag/9

and plus Needle - Android

的多线程库

http://zsoltsafrany.github.io/needle/

如果您不喜欢第三方库,而更喜欢简单且有良好文档和支持的库,Loaders 是最佳选择。

令我们高兴的是,AsyncTaskLoader(Loaders 的子类)执行与 AsyncTask 相同的功能,但更好,并且还可以处理更多 Activity 配置更改 easily.And 最好的事情是它在生活中的表现Fragments 和 Activity 的循环。

有关更多信息和子类,请查看此 documentation

应该使用加载器而不是直接使用异步任务。有特定的 Loader API 用于特定的操作,例如在 sqlite 数据库中执行事务等。

RxJAVA 是最好的选择

用于 Web 服务调用、文件上传、文件下载的 Asynctask 的替代方法是 Android Fast Networking Lib

对于其他情况 您可以使用以下 method

 Disposable d = Observable.fromCallable(new Callable<HashMap<String, String>>() {
            @Override
            public HashMap<String, String> call() throws Exception {
            // will run in background thread (same as doinBackground)
                return postParam;
            }
        })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<HashMap<String, String>>() {
                    @Override
                    public void accept(final HashMap<String, String> data) throws Exception {

        // will run in UI thread. write down code for on PostExecute
                    }

                });
    // write down code for on preExecute
        DisposableManager.add(d);

// 处理对象

@Override
    protected void onDestroy() {
        super.onDestroy();
        DisposableManager.dispose();
    }
        // Dispose manager class


 import io.reactivex.disposables.CompositeDisposable;
    import io.reactivex.disposables.Disposable;

    public class DisposableManager {

        private static CompositeDisposable compositeDisposable;

        public static void add(Disposable disposable) {
            getCompositeDisposable().add(disposable);
        }

        public static void dispose() {
            getCompositeDisposable().dispose();
        }

        private static CompositeDisposable getCompositeDisposable() {
            if (compositeDisposable == null || compositeDisposable.isDisposed()) {
                compositeDisposable = new CompositeDisposable();
            }
            return compositeDisposable;
        }

        private DisposableManager() {}
    }

我有 post 有多种解决方案可以替代 asynctask,例如使用

  1. 执行者服务
  2. RxJava
  3. 可听期货
  4. 使用 Kotlin 的 Courotines

这是我的实现

使用 KotlinCoroutines 自己实现很简单:

fun <P, R> CoroutineScope.executeAsyncTask(
        onPreExecute: () -> Unit,
        doInBackground: suspend (suspend (P) -> Unit) -> R,
        onPostExecute: (R) -> Unit,
        onProgressUpdate: (P) -> Unit
) = launch {
    onPreExecute()

    val result = withContext(Dispatchers.IO) {
        doInBackground {
            withContext(Dispatchers.Main) { onProgressUpdate(it) }
        }
    }
    onPostExecute(result)
}

executeAsyncTaskCoroutineScope 上的扩展函数。有任何 CoroutineScope 实例与 Dispatchers.Main 上下文,例如 viewModelScope 我们可以像下面这样调用这个函数:

viewModelScope.executeAsyncTask(
    onPreExecute = {
        // ... runs in Main Thread
    }, doInBackground = { publishProgress: suspend (progress: Int) -> Unit ->
        
        // ... runs in Background Thread

        // simulate progress update
        publishProgress(50) // call `publishProgress` to update progress, `onProgressUpdate` will be called
        delay(1000)
        publishProgress(100)

        
        "Result" // send data to "onPostExecute"
    }, onPostExecute = {
        // runs in Main Thread
        // ... here "it" is a data returned from "doInBackground"
    }, onProgressUpdate = {
        // runs in Main Thread
        // ... here "it" contains progress
    }
)

主要条件是 CoroutineScope 应该有 Dispatchers.Main 上下文。 viewModelScope 默认有。