以下は、更新ボタンと停止ボタンの 1 つだけが表示される 2 つのボタンを持つ Android アクティビティのサンプル コードです。
このコードは次のことを行います。
[更新] をクリックすると、いくつかの AsyncTask が開始されます。タスクの preExecute により、更新ボタンが非表示になり、停止ボタンが表示されます。タスクの postExecute は、実行中のタスクがもうないかどうかを確認し、そうであれば更新ボタンを表示し、停止ボタンを非表示にします。
停止がクリックされた場合: すべてのタスクがキャンセルされ、更新ボタンが表示され、停止ボタンが非表示になります。
このコードは問題なく動作しますが、例外が 1 つあります。タスクの実行中に画面の向きを変更してアクティビティを再作成する場合です。ボタンは xml で定義された状態に戻ります (refresh=visibil、stop=gone)。
静的変数を使用して可視性の現在の状態を追跡すると、状況が悪化するだけです。これは、可視性を元に戻す必要がある実行中のタスクは、その時点で停止または破棄されている呼び出し元のアクティビティのビューしか変更できないためです。
public class MainActivity extends Activity
{
private static List<MyAsyncTask> activeTasks = new LinkedList<MyAsyncTask>();
private View refresh;
private View stop;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
this.setContentView(R.layout.activity_main);
this.refresh = findViewById(R.id.refresh);
this.refresh.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{ // Start a couple tasks
new MyAsyncTask(MainActivity.this).execute();
new MyAsyncTask(MainActivity.this).execute();
}
});
this.stop = findViewById(R.id.stop);
this.stop.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{ // Cancel all tasks and toggle refresh button
cancelAll();
MainActivity.this.enableRefresh(true);
}
});
}
public void enableRefresh(boolean enable)
{
if (this.refresh != null && this.stop != null)
{
this.refresh.setVisibility(enable ? View.VISIBLE : View.GONE);
this.stop.setVisibility(!enable ? View.VISIBLE : View.GONE);
}
}
public static void cancelAll()
{
for (MyAsyncTask task : MainActivity.activeTasks)
task.cancel(true);
MainActivity.activeTasks = new LinkedList<MyAsyncTask>();
}
private class MyAsyncTask extends AsyncTask<Void,Void,Void>
{
private MainActivity activity;
public MyAsyncTask(MainActivity activity)
{
this.activity = activity;
}
@Override
protected void onPreExecute()
{
MainActivity.activeTasks.add(this);
this.activity.enableRefresh(false);
}
@Override
protected Void doInBackground(Void... v)
{
try
{ // Simulate a task
Thread.sleep(3000);
}
catch (InterruptedException e)
{
}
return null;
}
@Override
protected void onPostExecute(Void v)
{
MainActivity.activeTasks.remove(this);
if (MainActivity.activeTasks.size() == 0)
this.activity.enableRefresh(true);
}
}
}