使用进度对话框而不是asyncTask中的进度条

时间:2014-03-09 09:47:22

标签: android android-asynctask

我正在尝试实现此tutorial,以便在运行后台任务时处理配置更改。一切正常,配置更改后应用程序不会崩溃。在本教程中,进度条用于显示进度。但在我自己的实现中,我想使用进度对话框。

我已经使用了很多次进度Dialog,所以调用它并开始出现并不是问题所在。我的问题是,与进度条不同,进度对话框在配置更改时被忽略。就像那样。

这是我的代码:

我的主要活动:

 private TaskFragment mTaskFragment;
 private ProgressDialog mProgressDialog;
 private TextView mPercent;
 private Button mButton;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
 Log.i(TAG, "onCreate(Bundle)");
 super.onCreate(savedInstanceState);
 setContentView(R.layout.main);

 // Initialize views


 mButton = (Button) findViewById(R.id.task_button);
 mButton.setOnClickListener(new OnClickListener() {
 @Override
 public void onClick(View v) {
 if (mTaskFragment.isRunning()) {
  mTaskFragment.cancel();
 } else {
  mTaskFragment.start();
 }
 }
 });

 mProgressBar = new ProgressDialog(this);



  FragmentManager fm = getSupportFragmentManager();
  mTaskFragment = (TaskFragment) fm.findFragmentByTag("task");

  // If the Fragment is non-null, then it is currently being
 // retained across a configuration change.
 if (mTaskFragment == null) {
 mTaskFragment = new TaskFragment();
 fm.beginTransaction().add(mTaskFragment, "task").commit();  
 }

 if (mTaskFragment.isRunning()) {
 mButton.setText(getString(R.string.cancel));
 } else {
 mButton.setText(getString(R.string.start));
 }
 }



 /****************************/
 /***** CALLBACK METHODS *****/
 /****************************/

 @Override
 public void onPreExecute() {
 Log.i(TAG, "onPreExecute()");

 mProgressBar.setTitle("Wacky");
 mProgressBar.setMessage("wack");
 mProgressBar.setIndeterminate(true);
 mProgressBar.show();
 mButton.setText(getString(R.string.cancel));

 mButton.setText(getString(R.string.cancel));
 Toast.makeText(this, R.string.task_started_msg, Toast.LENGTH_SHORT).show();
 }

 @Override
 public void onProgressUpdate(int percent) {
 //Log.i(TAG, "onProgressUpdate(" + percent + "%)");

 }

 @Override
 public void onCancelled() {
 Log.i(TAG, "onCancelled()");
 mButton.setText(getString(R.string.start));

 Toast.makeText(this, R.string.task_cancelled_msg, Toast.LENGTH_SHORT).show();
 }

 @Override
 public void onPostExecute() {
 Log.i(TAG, "onPostExecute()");
 mButton.setText(getString(R.string.start));

 Toast.makeText(this, R.string.task_complete_msg, Toast.LENGTH_SHORT).show();
 }

我的无头片段,包含我的asyncTask

 /**
 *   This Fragment manages a single background task and retains itself across
 * configuration changes.
 */
 public class TaskFragment extends Fragment {
 public static final String TAG = TaskFragment.class.getSimpleName();

 /**
 * Callback interface through which the fragment can report the task's
 * progress and results back to the Activity.
 */

 public static interface TaskCallbacks {
    public void onPreExecute();
    public void onProgressUpdate(int percent);
    public void onCancelled();
    public void onPostExecute();
  }

 public TaskCallbacks mCallbacks;
 public DummyTask mTask;
 public boolean mRunning;

 /**
 * Android passes us a reference to the newly created Activity by calling this
 * method after each configuration change.
 */
 @Override
 public void onAttach(Activity activity) {
 Log.i(TAG, "onAttach(Activity)");
 super.onAttach(activity);
 if (!(activity instanceof TaskCallbacks)) {
  throw new IllegalStateException("Activity must implement the TaskCallbacks interface.");
 }

 // Hold a reference to the parent Activity so we can report back the task's
 // current progress and results.
 mCallbacks = (TaskCallbacks) activity;
 }

 /**
 * This method is called only once when the Fragment is first created.
 */
 @Override
 public void onCreate(Bundle savedInstanceState) {
 Log.i(TAG, "onCreate(Bundle)");
 super.onCreate(savedInstanceState);
 setRetainInstance(true);
 }

 /**
 * This method is <em>not</em> called when the Fragment is being retained
 * across Activity instances.
 */
 @Override
 public void onDestroy() {
 Log.i(TAG, "onDestroy()");
 super.onDestroy();
 cancel();
 }

 /*****************************/
 /***** TASK FRAGMENT API *****/
 /*****************************/

 /**
 * Start the background task.
 */
 public void start() {
 if (!mRunning) {
  mTask = new DummyTask(this, mCallbacks);
  mTask.execute();
  mRunning = true;
 }
 }

 /**
 * Cancel the background task.
 */
 public void cancel() {
 if (mRunning) {
  mTask.cancel(false);
  mTask = null;
  mRunning = false;
 }
 }

 /**
 * Returns the current state of the background task.
 */
 public boolean isRunning() {
 return mRunning;
 }

 @Override
 public void onActivityCreated(Bundle savedInstanceState) {
 Log.i(TAG, "onActivityCreated(Bundle)");
 super.onActivityCreated(savedInstanceState);
 }
 }

我的后台任务(在单独的外部课程中)

 /**
 * A dummy task that performs some (dumb) background work and proxies progress
 * updates and results back to the Activity.
 */
 public class DummyTask extends AsyncTask<Void, Integer, Void> {
private  TaskFragment fragment;
private TaskCallbacks callbacks;
private ProgressDialog mProgressBar;
MainActivity activity;

 public DummyTask(TaskFragment taskFragment, TaskCallbacks mCallbacks) {
    // TODO Auto-generated constructor stub

  this.fragment = taskFragment;
  this.callbacks = mCallbacks;
}

 @Override
 protected void onPreExecute() {
 // Proxy the call to the Activity
 fragment.mCallbacks.onPreExecute();
 fragment.mRunning = true;
 }

 @Override
 protected Void doInBackground(Void... ignore) {
 for (int i = 0; !isCancelled() && i < 100; i++) {

   //Log.i(TAG, "publishProgress(" + i + "%)");
   SystemClock.sleep(100);
   publishProgress(i);
 }
 return null;
 }

 @Override
 protected void onProgressUpdate(Integer... percent) {
 // Proxy the call to the Activity
 fragment.mCallbacks.onProgressUpdate(percent[0]);
 }

 @Override
 protected void onCancelled() {
 // Proxy the call to the Activity
 fragment.mCallbacks.onCancelled();
 fragment.mRunning = false;
 }

 @Override
 protected void onPostExecute(Void ignore) {
 // Proxy the call to the Activity
 fragment.mCallbacks.onPostExecute();
 fragment.mRunning = false;
 }
 }

我认为这是我在主要活动的onCreate方法中传递进度对话框的上下文。谢谢你的帮助。

1 个答案:

答案 0 :(得分:0)

首先,Activity是Context的子类,你应该已经知道了。其次,如果Activity被销毁,它就不再有窗口了。第三,Dialog使用Context(读取Activity)不是因为它需要,而是因为它使用与Activity相关联的窗口来显示它自己 它应该是完全可以理解的,为什么在配置更改期间销毁活动后,对话框不再可见。

保留您使用的对象的方法很好,但它不能保留在配置更改期间会被销毁的任何内容,例如与非应用程序上下文相关的任何对象,每次上下文更改时您需要手动创建所有这些对象

您应该使用onSaveInstanceState(Bundle)来存储ProgressDialog的状态(是否显示),并使用存储在Bundle中的值在onCreate(Bunde)中再次显示。

只是一个例子

@Override
protected void onSaveInstanceState(Bundle outState){
    super.onSaveInstanceState(outState);
    outState.putBoolean("SHOW_DIALOG", mProgressBar.isShowing());
}

//...

@Override
protected void onCreate(Bundle savedInstanceState) {
    //...
    if (savedInstanceState != null){
        if (savedInstanceState.getBoolean("SHOW_DIALOG") && mTaskFragment.isRunning()){
            mProgressBar.setTitle("Wacky");
            mProgressBar.setMessage("wack");
            mProgressBar.setIndeterminate(true);
            mProgressBar.show();
        }
    }
    //...