Один Word: Повышение. InterProcess. Если это действительно должно быть быстро, общая память является способом пойти. У Вас почти есть нуль наверху, поскольку операционная система делает обычное отображение между виртуальными и физическими адресами, и никакая копия не требуется для данных. Вы просто имеете к наблюдению за проблемами параллелизма.
Для того, чтобы на самом деле отправить команды как завершение работы и запрос , я использовал бы очереди сообщений. Я ранее использовал localhost сетевое программирование, чтобы сделать это и использовал ручное выделение общей памяти, прежде чем я знал о повышении. Чертовски, если бы я должен был бы переписать приложение, я сразу выбрал бы повышение. Повышение. InterProcess делает это более легким для Вас. Проверьте его.
Одним из решений этой проблемы является использование метода Handler.postDelayed(). Некоторые учебные материалы Google предлагают такое же решение.
@Override
public void onClick(View v) {
my_button.setBackgroundResource(R.drawable.icon);
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
my_button.setBackgroundResource(R.drawable.defaultcard);
}
}, 2000);
}
Однако некоторые отмечают, что приведенное выше решение приводит к утечке памяти, поскольку в нем используется нестатический внутренний и анонимный класс, который неявно содержит ссылку на свой внешний класс, активность. Это является проблемой, когда контекст активности собирается в мусор.
Более сложное решение, позволяющее избежать утечки памяти, предусматривает подклассы Handler
и Runnable
со статическими внутренними классами внутри activity, поскольку статические внутренние классы не содержат неявной ссылки на свой внешний класс:
private static class MyHandler extends Handler {}
private final MyHandler mHandler = new MyHandler();
public static class MyRunnable implements Runnable {
private final WeakReference<Activity> mActivity;
public MyRunnable(Activity activity) {
mActivity = new WeakReference<>(activity);
}
@Override
public void run() {
Activity activity = mActivity.get();
if (activity != null) {
Button btn = (Button) activity.findViewById(R.id.button);
btn.setBackgroundResource(R.drawable.defaultcard);
}
}
}
private MyRunnable mRunnable = new MyRunnable(this);
public void onClick(View view) {
my_button.setBackgroundResource(R.drawable.icon);
// Execute the Runnable in 2 seconds
mHandler.postDelayed(mRunnable, 2000);
}
Обратите внимание, что Runnable
использует WeakReference на Activity, что необходимо для статического класса, которому нужен доступ к UI.
Вы, вероятно, не захотите делать это таким образом. Поместив явное sleep ()
в обработчик событий, вызываемых нажатием кнопки, вы фактически заблокируете весь пользовательский интерфейс на секунду. Одна альтернатива - использовать какой-нибудь однократный таймер . Создайте TimerTask , чтобы изменить цвет фона обратно на цвет по умолчанию, и запланируйте его на таймере.
Другой вариант - использовать Handler . Есть учебник о ком-то, кто переключился с использования таймера на использование обработчика.
Между прочим, вы не можете приостановить процесс. Процесс Java (или Android) имеет по крайней мере 1 поток, и вы можете только спящие потоки.
В дополнение к ответам г-на Янковского вы также можете использовать postDelayed ()
. Это доступно в любом представлении
(например, вашей карте) и требует Runnable
и периода задержки. После этой задержки выполняется Runnable
.
Это то, что я сделал в конце дня - теперь работает нормально:
@Override
public void onClick(View v) {
my_button.setBackgroundResource(R.drawable.icon);
// SLEEP 2 SECONDS HERE ...
final Handler handler = new Handler();
Timer t = new Timer();
t.schedule(new TimerTask() {
public void run() {
handler.post(new Runnable() {
public void run() {
my_button.setBackgroundResource(R.drawable.defaultcard);
}
});
}
}, 2000);
}