我有一个Activity来实现一个保留的片段来执行一个耗时的任务。这允许我旋转屏幕而不会丢失对异步任务的引用,也不会阻止它被执行。我在活动上有一个按钮来启动异步任务。每次创建活动时(例如,由于旋转的屏幕),活动都会检查其保留的片段是否正在运行异步任务。如果是这样,它会显示progressDialog,让用户知道仍有一些任务在后台运行。我附上了我提到的代码。实际上它有效。然而,奇怪的是它每次都有效,但第一次!当我第一次按下按钮启动异步过程时,不显示progressDialog,尽管" onPreExecute()"被调用和行" progressDialog.show()"执行。如果我在按下按钮后旋转屏幕,则显示progressDialog,当进程结束时,如果我再次按下按钮,那么它可以正常工作。正如我所说,它除了第一个以外一直在工作。知道为什么吗?
谢谢!
活动
public class Activity extends AppCompatActivity implements ActivityTaskFragment.TaskCallbacks{
private ProgressDialog progressDialog;
private static final String TAG_TASK_FRAGMENT = "task_fragment";
private ActivityTaskFragment activityTaskFragment;
//Some additional code here
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_crear_turno);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
//------------------------------------------------------
setListeners();
setFragment();
createProgressDialog();
showProgressDialog();
}
private void showProgressDialog()
{
if(activityTaskFragment!=null)
{
if(activityTaskFragment.isRunning())
{
progressDialog.show();
}
}
}
private void setFragment()
{
FragmentManager fm = getFragmentManager();
activityTaskFragment = (ActivityTaskFragment) fm.findFragmentByTag(TAG_TASK_FRAGMENT);
// If the Fragment is non-null, then it is currently being
// retained across a configuration change.
if (activityTaskFragment == null) {
activityTaskFragment = new ActivityTaskFragment();
fm.beginTransaction().add(activityTaskFragment, TAG_TASK_FRAGMENT).commit();
}
}
private void setListeners() {
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
activityTaskFragment.execute();
}
});
}
//fragment interface implementation
@Override
public void onPreExecute()
{
if(progressDialog!=null)
progressDialog.show();
}
@Override
public void onCancelled() {
if(progressDialog!=null)
{
if(progressDialog.isShowing())
{
progressDialog.dismiss();
}
}
}
@Override
public void onPostExecute()
{
if(progressDialog!=null)
{
if(progressDialog.isShowing())
{
progressDialog.dismiss();
}
}
}
private void createProgressDialog()
{
if(progressDialog == null)
{
progressDialog = new ProgressDialog(Activity.this);
progressDialog.setTitle("Executing job");
progressDialog.setMessage("please wait...");
}
}
}
TaskFragment
/**
* This Fragment manages a single background task and retains
* itself across configuration changes.
*/
public class ActivityTaskFragment extends Fragment {
/**
* Callback interface through which the fragment will report the
* task's progress and results back to the Activity.
*/
interface TaskCallbacks {
void onPreExecute();
void onCancelled();
void onPostExecute();
}
private TaskCallbacks mCallbacks;
private CheckTask mTask;
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
mCallbacks = (TaskCallbacks) activity;
}
/**
* Hold a reference to the parent Activity so we can report the
* task's current progress and results. The Android framework
* will pass us a reference to the newly created Activity after
* each configuration change.
*/
public void execute()
{
mTask.cancel(true);
mTask = new CheckTask();
mTask.execute();
}
public void cancel()
{
if(mTask != null)
{
mTask.cancel(true);
}
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
if(context instanceof Activity) {
Activity activity = (Activity) context;
mCallbacks = (TaskCallbacks) activity;
}
}
/**
* This method will only be called once when the retained
* Fragment is first created.
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Retain this fragment across configuration changes.
setRetainInstance(true);
mTask = new CheckTask();
}
/**
* Set the callback to null so we don't accidentally leak the
* Activity instance.
*/
@Override
public void onDetach() {
super.onDetach();
mCallbacks = null;
}
/**
* A dummy task that performs some (dumb) background work and
* proxies progress updates and results back to the Activity.
*
* Note that we need to check if the callbacks are null in each
* method in case they are invoked after the Activity's and
* Fragment's onDestroy() method have been called.
*/
private class CheckTask extends AsyncTask<Void, Void, Void> {
@Override
protected void onPreExecute()
{
if (mCallbacks != null) {
mCallbacks.onPreExecute();
}
}
/**
* Note that we do NOT call the callback object's methods
* directly from the background thread, as this could result
* in a race condition.
*/
@Override
protected Void doInBackground(Void... ignore) {
/*
LONG TIME CONSUMING TASK
*/
return null;
}
@Override
protected void onCancelled() {
running = false;
if (mCallbacks != null) {
mCallbacks.onCancelled();
}
}
@Override
protected void onPostExecute(Void ignore)
{
running = false;
if (mCallbacks != null) {
mCallbacks.onPostExecute();
}
}
}
public boolean isRunning()
{
if(mTask!=null)
{
if(mTask.getStatus() == AsyncTask.Status.RUNNING)
{
return true;
}
else
{
return false;
}
}
else
{
return false;
}
}
}