tlu*_*dek 9 android design-patterns android-asynctask
我想AsyncTask在我的应用程序中使用for来管理一些业务逻辑.使用separed文件onProgressUpdate(...)中AsyncTask定义的方法的最佳模式是什么(不是作为一个类的Activity)我有两个想法:
1.最简单的方法:创建ProgressDialogin Activity(使用onCreateDialog(...)方法)并通过AsyncTask构造函数传递对我的子类的引用(覆盖onProgressUpdate(...)里面)我的AsyncTask子类).此解决方案的缺点是在业务逻辑代码中使用UI组件.
FooTask1.java:
public class FooTask1 extends AsyncTask<Void, Integer, Void> {
private ProgressDialog mProgressDialog;
public FooTask1(ProgressDialog progressDialog) {
super();
mProgressDialog = progressDialog;
}
@Override
protected Void doInBackground(Void... unused) {
// time consuming operation
for (int i=0; i<=100; i++) {
this.publishProgress(i);
try {
Thread.sleep(100);
} catch (Exception e) {}
}
return null;
}
@Override
protected void onProgressUpdate(Integer... progress) {
mProgressDialog.setProgress(progress[0]);
}
@Override
protected void onPostExecute(Void result) {
mProgressDialog.dismiss();
}
}
Run Code Online (Sandbox Code Playgroud)
FooActivity1.java:
public class FooActivity1 extends Activity {
private static final int DIALOG_PROGRESS_ID = 0;
private ProgressDialog mProgressDialog;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
showDialog(DIALOG_PROGRESS_ID);
new FooTask(mProgressDialog).execute();
}
@Override
protected Dialog onCreateDialog(int id) {
switch(id) {
case DIALOG_PROGRESS_ID:
mProgressDialog = new ProgressDialog(this);
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
mProgressDialog.setMessage("Loading...");
mProgressDialog.setCancelable(false);
return mProgressDialog;
default:
return null;
}
}
}
Run Code Online (Sandbox Code Playgroud)
2.更复杂的方法:覆盖类内部的onProgressUpdate(...)方法:AsyncTaskActivity
FooTask2.java:
public class FooTask2 extends AsyncTask<Void, Integer, Void> {
@Override
protected Void doInBackground(Void... unused) {
// time consuming operation
for (int i=0; i<=100; i++) {
this.publishProgress(i);
try {
Thread.sleep(100);
} catch (Exception e) {}
}
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
FooActivity2.java
public class FooActivity2 extends Activity {
private static final int DIALOG_PROGRESS_ID = 0;
private ProgressDialog mProgressDialog;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
showDialog(DIALOG_PROGRESS_ID);
new FooTaskLoader().execute();
}
@Override
protected Dialog onCreateDialog(int id) {
switch(id) {
case DIALOG_PROGRESS_ID:
mProgressDialog = new ProgressDialog(this);
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
mProgressDialog.setMessage("Loading...");
mProgressDialog.setCancelable(false);
return mProgressDialog;
default:
return null;
}
}
private class FooTaskLoader extends FooTask2 {
@Override
protected void onProgressUpdate(Integer... progress) {
mProgressDialog.setProgress(progress[0]);
}
@Override
protected void onPostExecute(Void result) {
dismissDialog(DIALOG_PROGRESS_ID);
}
}
}
Run Code Online (Sandbox Code Playgroud)
yor*_*rkw 13
我宁愿从AsyncTask中隔离业务逻辑内容而不是从Activity中隔离AsyncTask.
一般来说,AsyncTask在Android应用程序生命周期中有一个非常具体的设计和用例,即在后台线程中运行一些耗时的任务,一旦完成,在UI线程中更新Activity的视图.这就是为什么总是建议将它用作Activity的内部类.
更多的OO设计IMO正在将您的业务逻辑隔离并集中到POJO(用于可重用性).为了测试,您可以执行以下操作:
1.定义接口IBusinessDAO
2.定义RealBusinessDAO实现IBusinessDAO
3.定义MockBusinessDAO实现IBusinessDAO
4.调用IBusinessDAO.foo(); 在AsyncTask.doInBackground()里面
对于单元测试您的业务逻辑,因为它是一个POJO,您可以使用纯JUnit编写您的测试用例.有时候我们想测试UI组件而我们并不关心底层业务逻辑是如何实现的,例如,我的业务逻辑连接到远程http服务器下载一些json数据,我不想每次都这样做我只是想要测试UI布局,对于这种情况,我可以轻松更改我的Activity使用MockBusinessDAO(有点像Spring的DI概念),如下所示:
public class MyActivity extends Activity {
IBusinessDAO businessDAO;
... ...
private class MyAsyncTask extends AsyncTask<Void, Void, Void> {
... ...
protected void doInBackground(Void... params) {
businessDAO.foo();
}
}
... ...
public void onCreate(Bundle savedInstanceState) {
if (runInTest)
businessDAO = new MockBusinessDAO();
else
businessDAO = new RealBusinessDAO();
new myAsyncTask().execute();
}
}
Run Code Online (Sandbox Code Playgroud)
这样做的一些优点是:
1.AsyncTask实现简单而干净(doInBacnground()中的几行代码)
2.业务逻辑实现纯粹是POJO,提高了可重用性.
3.隔离测试业务逻辑和UI组件,提高可测试性.
希望有所帮助.
| 归档时间: |
|
| 查看次数: |
7063 次 |
| 最近记录: |