Я пытаюсь предотвратить загрузку активности дважды, если я дважды нажимаю кнопку сразу после первого щелчка.
У меня есть действие, которое загружается при нажатии кнопки, например
myButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
//Load another activity
}
});
Теперь, поскольку загружаемое действие имеет сетевые вызовы, загрузка занимает немного времени (MVC). Я показываю для этого вид загрузки, но если я дважды нажму кнопку перед этим, я могу увидеть, что действие загружается дважды.
Кто-нибудь знает, как это предотвратить?
android
button
android-activity
onclick
теджас
источник
источник
Ответы:
В прослушивателе событий кнопки отключите кнопку и покажите другое действие.
Button b = (Button) view; b.setEnabled(false); Intent i = new Intent(this, AnotherActitivty.class); startActivity(i);
Переопределить,
onResume()
чтобы снова включить кнопку.@Override protected void onResume() { super.onResume(); Button button1 = (Button) findViewById(R.id.button1); button1.setEnabled(true); }
источник
Добавьте это к своему
Activity
определению вAndroidManifest.xml
...android:launchMode = "singleTop"
Например:
<activity android:name=".MainActivity" android:theme="@style/AppTheme.NoActionBar" android:launchMode = "singleTop"/>
источник
android:launchMode = "singleTop"
эффекта, не нарушая многозадачности Android. В документации указано, что большинство приложений не должны использовать этуsingleInstance
опцию.Вы можете использовать такие флаги намерений.
Intent intent = new Intent(Class.class); intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); activity.startActivity(intent);
Это сделает открытыми только одно действие в верхней части стека истории.
источник
android:launchMode = "singleTop"
таким образом он решается без добавления флага к каждому Intent.Поскольку SO не позволяет мне комментировать другие ответы, я должен засорить этот поток новым ответом.
Общие ответы на проблему «активность открывается дважды» и мой опыт использования этих решений (Android 7.1.1):
РЕДАКТИРОВАТЬ: Это было для начала действий с startActivity (). При использовании startActivityForResult () мне нужно установить как FLAG_ACTIVITY_SINGLE_TOP, так и FLAG_ACTIVITY_CLEAR_TOP.
источник
Это работало для меня только тогда, когда
startActivity(intent)
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
источник
android:launchMode = "singleInstance"
в файл манифеста вашего тега активности?Используйте singleInstance, чтобы избежать повторного вызова активности.
<activity android:name=".MainActivity" android:label="@string/activity" android:launchMode = "singleInstance" />
источник
Допустим, @wannik прав, но если у нас есть более 1 кнопки, вызывающей один и тот же слушатель действия, и я нажимаю две кнопки почти одновременно, прежде чем начать следующее действие ...
Так что хорошо, если у вас есть поле
private boolean mIsClicked = false;
и в слушателе:if(!mIsClicked) { mIsClicked = true; Intent i = new Intent(this, AnotherActitivty.class); startActivity(i); }
И
onResume()
нам нужно вернуть состояние:@Override protected void onResume() { super.onResume(); mIsClicked = false; }
В чем разница между моим ответом и ответом @wannik?
Если вы установите для параметра enabled значение false в прослушивателе вызывающего просмотра, другая кнопка, использующая тот же прослушиватель, все равно будет включена. Поэтому, чтобы быть уверенным, что действие слушателя не вызывается дважды, вам нужно иметь что-то глобальное, что отключает все вызовы слушателя (неважно, новый ли это экземпляр или нет)
В чем разница между моим ответом и другими?
Они думают правильно, но не думают о будущем возвращении к тому же экземпляру вызывающей активности :)
источник
synchronized(mIsClicked) {...}
чтобы быть на 100% безопасным.В этой ситуации я выберу один из двух подходов:
singleTask
в manifest.xml ИЛИ флаг в методахonResume()
& ActivityonDestroy()
соответственно.Для первого решения: я предпочитаю использовать
singleTask
для действия в манифесте, а неsingleInstance
, согласно использованию,singleInstance
я понял, что в некоторых случаях действие создает новый отдельный экземпляр для себя, что приводит к появлению двух отдельных окон приложений в запущенных приложениях. в bcakground и помимо дополнительных выделений памяти, которые могут привести к очень плохому взаимодействию с пользователем, когда пользователь открывает представление приложений, чтобы выбрать какое-то приложение для возобновления. Итак, лучший способ - определить активность в manifest.xml следующим образом:<activity android:name=".MainActivity" android:launchMode="singleTask"</activity>
Вы можете проверить режимы запуска активности здесь .
Для второго решения вам нужно просто определить статическую переменную или предпочтительную переменную, например:
public class MainActivity extends Activity{ public static boolean isRunning = false; @Override public void onResume() { super.onResume(); // now the activity is running isRunning = true; } @Override public void onDestroy() { super.onDestroy(); // now the activity will be available again isRunning = false; } }
а с другой стороны, когда вы хотите запустить это действие, просто проверьте:
private void launchMainActivity(){ if(MainActivity.isRunning) return; Intent intent = new Intent(ThisActivity.this, MainActivity.class); startActivity(intent); }
источник
Я думаю, вы неправильно решаете проблему. Как правило, выполнение длительных веб-запросов с помощью любого из методов жизненного цикла запуска (
onCreate()
,onResume()
и т. Д.) - плохая идея . На самом деле эти методы следует просто использовать для создания экземпляров и инициализации объектов, которые будет использовать ваша деятельность, и поэтому они должны быть относительно быстрыми.Если вам нужно выполнить веб-запрос, сделайте это в фоновом потоке из вашего недавно запущенного действия (и покажите диалог загрузки в новом действии). После завершения потока фонового запроса он может обновить активность и скрыть диалог.
Тогда это означает, что ваше новое действие должно быть запущено немедленно и предотвратить двойной щелчок.
источник
Надеюсь это поможет:
protected static final int DELAY_TIME = 100; // to prevent double click issue, disable button after click and enable it after 100ms protected Handler mClickHandler = new Handler() { public void handleMessage(Message msg) { findViewById(msg.what).setClickable(true); super.handleMessage(msg); } }; @Override public void onClick(View v) { int id = v.getId(); v.setClickable(false); mClickHandler.sendEmptyMessageDelayed(id, DELAY_TIME); // startActivity() }`
источник
Другое очень-очень простое решение, если вы не хотите использовать,
onActivityResult()
- отключить кнопку на 2 секунды (или на время, которое вы хотите), не идеально, но может частично решить проблему в некоторых случаях, и код прост:final Button btn = ... btn.setOnClickListener(new OnClickListener() { public void onClick(View v) { //start activity here... btn.setEnabled(false); //disable button //post a message to run in UI Thread after a delay in milliseconds btn.postDelayed(new Runnable() { public void run() { btn.setEnabled(true); //enable button again } },1000); //1 second in this case... } });
источник
// переменная для отслеживания времени события
private long mLastClickTime = 0;
2. В onClick проверьте, что если текущее время и разница во времени последнего щелчка меньше, чем 1 секунда, тогда ничего не делайте (возврат), иначе перейдите к событию щелчка
@Override public void onClick(View v) { // Preventing multiple clicks, using threshold of 1 second if (SystemClock.elapsedRealtime() - mLastClickTime < 1000) { return; } mLastClickTime = SystemClock.elapsedRealtime(); // Handle button clicks if (v == R.id.imageView2) { // Do ur stuff. } else if (v == R.id.imageView2) { // Do ur stuff. } } }
источник
Просто сохраните один флаг в методе button onClick как:
общедоступное логическое значение oneTimeLoadActivity = false;
myButton.setOnClickListener(new View.OnClickListener() { public void onClick(View view) { if(!oneTimeLoadActivity){ //start your new activity. oneTimeLoadActivity = true; } } });
источник
добавить режим запуска как отдельную задачу в манифест, чтобы активность не открывалась дважды при нажатии
<activity android:name=".MainActivity" android:label="@string/activity" android:launchMode = "singleTask" />
источник
Если вы используете onActivityResult, вы можете использовать переменную для сохранения состояния.
private Boolean activityOpenInProgress = false; myButton.setOnClickListener(new View.OnClickListener() { public void onClick(View view) { if( activityOpenInProgress ) return; activityOpenInProgress = true; //Load another activity with startActivityForResult with required request code } }); protected void onActivityResult(int requestCode, int resultCode, Intent data) { if( requestCode == thatYouSentToOpenActivity ){ activityOpenInProgress = false; } }
Работает и при нажатой кнопке «Назад», потому что код запроса возвращается при событии.
источник
myButton.setOnClickListener(new View.OnClickListener() { public void onClick(View view) { myButton.setOnClickListener(null); } });
источник
Используйте
flag
переменную, установите ееto true
, проверьте, истинно ли она, простоreturn
выполните Activity Call.Вы также можете использовать setClickable (false) для выполнения Activity Call
flg=false public void onClick(View view) { if(flg==true) return; else { flg=true; // perform click} }
источник
perform click; wait; flg = false;
когда мы вернемсяВы можете просто переопределить startActivityForResult и использовать переменную экземпляра:
boolean couldStartActivity = false; @Override protected void onResume() { super.onResume(); couldStartActivity = true; } @Override public void startActivityForResult(Intent intent, int requestCode, Bundle options) { if (couldStartActivity) { couldStartActivity = false; intent.putExtra(RequestCodeKey, requestCode); super.startActivityForResult(intent, requestCode, options); } }
источник
Вы также можете попробовать это
Button game = (Button) findViewById(R.id.games); game.setOnClickListener(new View.OnClickListener() { public void onClick(View view) { Intent myIntent = new Intent(view.getContext(), Games.class); startActivityForResult(myIntent, 0); } });
источник