android – 从AsyncTask管理ProgressDialog的最佳方式

前端之家收集整理的这篇文章主要介绍了android – 从AsyncTask管理ProgressDialog的最佳方式前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我想使用AsyncTask来管理我的应用程序中的一些业务逻辑.使用在separed文件中定义的AsyncTask的onProgressUpdate(…)方法的最佳模式是什么(而不是作为一个活动类别)
我有两个想法:
1.最简单的方法:在Activity中创建ProgressDialog(使用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();
}
}

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;
      }
  }
}

2.更复杂的方法:在Activity类中覆盖AsyncTask的onProgressUpdate(…)方法

FooTask2.java:

public class FooTask2 extends AsyncTask<Void,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;
}
}

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);
    }
}
}

解决方法

我宁愿从AsyncTask中隔离业务逻辑,而不是从Activity中分离AsyncTask.

一般来说,AsyncTask在Android应用程序生命周期中有一个非常具体的设计和用例,即在后台线程中运行一些耗时的任务,一旦完成,在UI线程中更新Activity的视图.这就是为什么总是推荐使用它作为一个内部的活动类.

更多的OO设计IMO将您的业务逻辑隔离并集中到POJO(为了可重用性).为了可测试性,您可以这样做:
1.定义界面IBusinessDAO
2.定义RealBusinessDAO实现IBusinessDAO
3.定义MockBusinessDAO实现IBusinessDAO
调用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();
  }


}

做这些的一些优点是:
1. AsyncTask实现简单干净(doInBacnground()中的几行代码)
业务逻辑实现纯粹是POJO,提高可重用性.
3.隔离测试业务逻辑和UI组件,提高可测试性.

希望有帮助

原文链接:https://www.f2er.com/android/310673.html

猜你在找的Android相关文章