#android #multithreading #broadcastreceiver #broadcast
#Android #многопоточность #broadcastreceiver #широковещательный
Вопрос:
У меня есть приложение, в котором я пытаюсь определить, КОГДА появляется подключение к Интернету и когда оно исчезает.
В тот момент, когда он появляется, я запускаю новый поток (отличный от пользовательского интерфейса), который соединяет мое приложение с удаленным сервером.
Для этого я вряд ли пытаюсь реализовать широковещательный приемник, который прослушивает подключение, но у меня возникают проблемы с пониманием концепции.
В моем onCreate()
у меня есть что-то вроде:
onCreate()
{
cThread = new Thread(new ClientThread(syncToken));
cThread.start();
}
Когда есть подключение к Интернету, я отправляю данные через сокет, когда нет, я сохраняю данные в базе данных. И когда появляется Интернет, я перезапускаю свой поток, чтобы повторно подключиться и отправить старые данные (которые не были отправлены из-за сбоя сети) и новые.
Допустим, я бы реализовал что-то вроде этого:
DoRefreshBroadcastReceiver refreshBroadcastReceiver;
...
onResume() {
// register the refreshing complete broadcast receiver
IntentFilter intentFilter = new IntentFilter(DO_REFRESH);
refreshBroadcastReceiver = new doRefreshBroadcastReceiver();
registerReceiver(refreshBroadcastReceiver, intentFilter);
}
public class DoRefreshBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// call method to run fetch code...
}
}
Означает ли это, что при обнаружении подключения к Интернету вызывается мой onReceive()
? И я мог бы начать свой поток там?
Какова концепция использования намерения? Потому что я действительно этого не понимаю. Как его использовать и какова его цель?
ИДЕЯ: я действительно не знаю, как использовать это намерение в этом случае или как использовать его в моем приложении!
Будет ли эта штука обнаруживать подключение к Интернету, даже если я не участвую в этой деятельности?
Редактировать:
Вот как выглядит мой onReceive:
onCreate()
{
cThread = new Thread(new ClientThread(syncToken));
// cThread.start();
connIntentFilter = new IntentFilter(
"android.net.conn.CONNECTIVITY_CHANGE");
connListener = new MyConnectivityListener();
}
public void onReceive(Context context, Intent intent)
{
mNetworkInfo = (NetworkInfo) intent
.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
if (mNetworkInfo != null amp;amp; mNetworkInfo.isConnected())
{
/*
* if(mNetworkInfo.getType()==ConnectivityManager.TYPE_WIFI);
*
*
* else
*/
cThread.start();
}
else {
System.out.println("There is no internet connection!");
try {
cThread.stop();
}
catch (Exception e) {
e.printStackTrace();
}
}
}
mNetworkInfo != null amp;amp; mNetworkInfo.isConnected()
Означает ли это, что он подключен, или я должен проверить определенный тип соединения в эмуляторе?
* Я думаю, что я должен запустить свой поток непосредственно в onReceive()
. Как только мое приложение запускается, оно обнаруживает подключение к Интернету и BroadcastReceiver
запускается, не так ли?
Комментарии:
1. Я прошу слишком многого?
Ответ №1:
Попробуйте что-то вроде этого…
public class MyActivity extends Activity {
private MyConnectivityListener connListener = null;
private IntentFiler connIntentFilter = null;
private Boolean connIntentFilterIsRegistered = false;
@Override
protected void onCreate(...) {
...
connIntentFilter = new IntentFilter("android.net.conn.CONNECTIVITY_CHANGE");
connListener = new MyConnectivityListener();
}
@Override
protected void onResume() {
...
if (!connIntentFilterIsRegistered) {
registerReceiver(connListener, connIntentFilter);
connIntentFilterIsRegistered = true;
}
}
@Override
protected void onPause() {
...
if (connIntentFilterIsRegistered) {
unregisterReceiver(connListener);
connIntentFilterIsRegistered = false;
}
}
protected class MyConnectivityListener extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// The NetworkInfo for the affected network is sent
// as an extra; it should be consulted to see what
// kind of connectivity event occurred.
}
}
}
BroadcastReceiver фактически является «слушателем», который прослушивает события, отправленные системой или, в некоторых случаях, вашими собственными компонентами приложения.
В этом случае система осуществляет широковещательную передачу android.net.conn.CONNECTIVITY_CHANGE
всякий раз, когда происходит изменение соединения (подключено / отключено). Зарегистрировав свой BroadcastReceiver для «прослушивания» этого события, вы можете получить extra
включенное в намерение из onReceive(...)
метода вашего BroadcastReceiver и сделать все, что вам нужно, соответственно. Дополнительный объект — это объект NetworkInfo, который будет содержать информацию о конкретной сети и о том, подключена она или нет.
Комментарии:
1. Если я помещу этот connIntentFilter = new IntentFilter («android.net.conn. CONNECTIVITY_CHANGE»); в моем onCreate () это та вещь, которая сообщает моей трансляции, когда изменяется состояние сети??? Мне не нужно что-то еще …? Во-вторых, в onReceive () я проверяю, что это за соединение … и если есть WiFi или что-то подобное, это означает, что я мог бы перезапустить свой поток … да ???….. И если подключен и все в порядке, могу ли я запустить свой поток в onReceive ()???? Или как работает эта часть перезапуска потока??? Спасибо, что еще немного прояснили ситуацию 🙂
2. @george: Бит в onCreate() предназначен просто для инициализации connIntentFilter именем «события», которое вы хотите прослушать. Затем вы передаете его
registerReceiver(...)
вместе с экземпляром вашего BroadcastReceiver. Регистрируясь, вы сообщаете системе, что хотите получать уведомления об изменении соединения. Проверив NetworkInfo в onReceive, вы можете определить, является ли «событие» подключением или разъединением, поэтому запустите / остановите свой поток соответствующим образом.3. Не могли бы вы, пожалуйста, взглянуть на редактирование моего вопроса, несколько последних вопросов: D! Большое вам спасибо
4. @george: Я думаю, ты в значительной степени там. Чтобы ответить на один вопрос — нет, приемник не будет продолжать работать после того, как вы оставите свою активность, если вы реализуете код в моем примере для отмены регистрации приемника в onPause () (что рекомендуется). Если вам нужно, чтобы он работал постоянно, тогда все становится сложнее. Я предлагаю вам поэкспериментировать с ним в том виде, в каком он есть сейчас, и узнать больше о том, как работают BroadcastReceivers и Intent broadcasts.
5. Если я запускаю свое приложение и у меня есть подключение к Интернету, оно подключается к удаленному серверу, но если я удалю подключение к Интернету, оно не отобразит никакой System.out.println () ….. или не подключится повторно к моему удаленному серверу