Android:AsyncTask 的替代方案?
Android: Alternatives to AsyncTask?
我为我的应用程序制作了一个框架,用于所有对外部网络的调用 API。我把所有东西都放在 "Services" 中,例如:UserService
、MessageService
等。所以现在当我想调用网络方法时,我不能在 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 无论如何都不适合这个?
您可以使用 Volley 库,它在后台线程上工作,并在事情完成后将控制权交还给主线程。
请记住 Android 有线程和 AsyncTasks 的限制。
您可以使用 2 个库来完成 AsyncTasks 的相同工作:
截击 -> http://www.androidhive.info/2014/05/android-working-with-volley-library-1/
LoopJ -> http://loopj.com/android-async-http/
更新:
我真的很推荐Retrofit 2。
http://square.github.io/retrofit/
有很多 AsyncTask 替代品:
and plus Needle - Android
的多线程库
如果您不喜欢第三方库,而更喜欢简单且有良好文档和支持的库,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,例如使用
- 执行者服务
- RxJava
- 可听期货
- 使用 Kotlin 的 Courotines
这是我的实现
使用 Kotlin 和 Coroutines 自己实现很简单:
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)
}
executeAsyncTask
是 CoroutineScope
上的扩展函数。有任何 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
默认有。
我为我的应用程序制作了一个框架,用于所有对外部网络的调用 API。我把所有东西都放在 "Services" 中,例如:UserService
、MessageService
等。所以现在当我想调用网络方法时,我不能在 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 无论如何都不适合这个?
您可以使用 Volley 库,它在后台线程上工作,并在事情完成后将控制权交还给主线程。
请记住 Android 有线程和 AsyncTasks 的限制。
您可以使用 2 个库来完成 AsyncTasks 的相同工作:
截击 -> http://www.androidhive.info/2014/05/android-working-with-volley-library-1/
LoopJ -> http://loopj.com/android-async-http/
更新:
我真的很推荐Retrofit 2。 http://square.github.io/retrofit/
有很多 AsyncTask 替代品:
and plus Needle - Android
的多线程库如果您不喜欢第三方库,而更喜欢简单且有良好文档和支持的库,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,例如使用
- 执行者服务
- RxJava
- 可听期货
- 使用 Kotlin 的 Courotines
这是我的实现
使用 Kotlin 和 Coroutines 自己实现很简单:
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)
}
executeAsyncTask
是 CoroutineScope
上的扩展函数。有任何 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
默认有。