私はゲームを書いています。ユーザーがレベルを終了すると、次のことが起こります。
- POSTを送信して、レベルレコードが破られたかどうかを確認します。(1-5秒)
- その場合は、
Dialog「名前を入力してください」と表示します。(速い) - ユーザーが[OK]をクリックしたら、自分のレコードとともにPOSTを送信します。(1-5秒)
ユーザーがレベルを終了すると、彼はになりGameActivityます。checkWorldRecord()が呼び出され、その中で、AsyncTaskが開始されます。
private void checkWorldRecord(final RecordType recordType, final double time, final int level)
{
new Handler(Looper.getMainLooper()).post(new Runnable()
{
@Override
public void run()
{
new DownloadTask(recordType, time, level).execute();
}
});
}
DownloadTask私が最初にリストしたこれらの3つのことをしています:
class DownloadTask extends AsyncTask<Void, Void, Void>
{
RecordType recordType;
double time;
int level;
public DownloadTask(RecordType recordType, double time, int level)
{
super();
this.recordType = recordType;
this.time = time;
this.level = level;
}
@Override
protected Void doInBackground(Void... params)
{
try
{
if (!Network.isWorldRecord(recordType, time, level)) // 1.
{
return null;
}
}
catch (Exception e)
{
return null;
}
Dialogs.showEnterNameAndSend(GameActivity.this, recordType, time, level, highScores.getGamesPlayed(),
highScores.getStars()); // 2.
return null;
}
}
ユーザーがゲームの後に待つとき、彼がにとどまっているなら、すべてがうまくいきますGameActivity。
問題は、次の場合です。
- ユーザーがゲームを終了しました。
checkWorldRecord()と呼ばれます。 - 別のスレッドで、最初のPOSTが開始されます。
- ユーザーが戻るボタンを押して、アクティビティを別のアクティビティに変更し
MainActivityます。 AsyncTaskチェックを終えて、新記録があります。showEnterNameAndSend()最初にビルドして後で表示したいAlertDialog。ブーム。私たちが通過していたのでGameActivity、そして今MainActivityが一番上にあります:
public static void showEnterNameAndSend(final Activity activity, final RecordType recordType, final double time,
final int level, final long gamesPlayed, final int stars)
{
AlertDialog.Builder builder = new AlertDialog.Builder(activity); // BOOM!!!
final EditText editText = new EditText(activity);
editText.setFilters(new InputFilter[]
{ new InputFilter.LengthFilter(Const.MAX_NAME_LENGTH) });
editText.setInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
builder.setView(editText);
builder.setTitle(recordType + " world record!");
builder.setMessage("Enter your name:");
builder.setPositiveButton("Ok", new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int whichButton)
{
String username = editText.getText().toString();
if (username.equals(""))
{
return;
}
try
{
Network.sendRecord(recordType, username, time, level, gamesPlayed, stars); // 3.
}
catch (Exception e)
{
showInternetError(activity);
}
}
});
showDialogOnUiThread(activity, builder);
}
private static void showDialogOnUiThread(Activity activity, final AlertDialog.Builder builder)
{
activity.runOnUiThread(new Runnable()
{
@Override
public void run()
{
builder.show();
}
});
}
はい、Context全体ではなく、Activityを渡すことも好みshowEnterNameAndSend()ます。ただし、showDialogOnUiThread()(によって呼び出されるshowEnterNameAndSend())は、 UIスレッドにActivityを表示するために、を必要とします。Dialogactivity.runOnUiThread()
これを修復する方法は?たぶん、例えば、いくつかの方法があるので、私は、すでに隠されている可能性があるgetCurrentActivity()を渡す必要はありませんか?Activityどういうわけかダイアログの表示をキャンセルできれば、ユーザーが閉じた後GameActivityも問題ありません。