- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个应用程序,我想在其中每隔 15 分钟查找一些数据。我有一个以警报启动的服务,但我还想在开始查找之前确保有网络连接。
为此,我认为我应该使用 BroadcastReceiver
来监视网络状态的更改。我包装了一个广播接收器来帮助解决这个问题:
public abstract class NetworkMonitor extends BroadcastReceiver
{
boolean mDoingStuff;
public abstract void doStuff();
public NetworkMonitor()
{
mDoingStuff = false;
IntentFilter networkStateFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
MyApp.getContext().registerReceiver(this, networkStateFilter);
}
@Override
public void onReceive(Context context, Intent intent)
{
// network state changes, you can process it, information in intent
ConnectivityManager cn = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo info = ConnectivityManagerCompat.getNetworkInfoFromBroadcast(cn, intent);
// Only use Wifi Connections for updating this
if (info.isConnectedOrConnecting() && !mDoingStuff)
{
mDoingStuff = true;
doStuff();
}
}
}
然后我在类似的服务中使用它:
public class WidgetUpdateService extends Service
{
@Override
public int onStartCommand(Intent intent, int flags, int startId)
{
// Build the async task to get the data
final MyAsyncTask mTask = new MyAsyncTask();
// Register an interest in when the network changes
new NetworkMonitor(false)
{
public void doStuff()
{
mTask.execute();
}
};
// Make sure that if we get shut down then we get started again correctly.
return START_REDELIVER_INTENT;
}
protected class MyAsyncTask extends AsyncTask<Void, Void, Void>
{
public MyAsyncTask()
{
}
@Override
protected Integer doInBackground(Void... arg0)
{
// do work
}
@Override
protected void onPostExecute(Integer result)
{
WidgetUpdateService.this.stopSelf();
}
@Override
protected void onCancelled(Integer result)
{
WidgetUpdateService.this.stopSelf();
}
}
}
其中 MyAsyncTask 是一个内部类,它将导致服务在完成时停止Self()。
这有点管用,但是:
NetworkMonitor()
实例,或者我可以只拥有一个像这样的匿名实例吗?查看文档,BroadcastReceiver
应该在 onReceive()
完成后自行清理。NetworkMonitor.mDoingStuff
?我猜如果我能弄清楚为什么 NetworkMonitor
在 onReceive()
完成后没有自行清理,那么我可能不再需要它了?如果您需要更多信息,请告诉我,我很乐意提供。
最佳答案
This kinda works
这是可怕的代码,恕我直言。
It seems that even when the service has been stopped (after the async task has finished correctly) the NetworkMonitor instance is still being receiving intents about changes to the network state. Why is this?
因为你永远不会注销接收器。它会继续运行,并像筛子一样泄漏内存,直到您的进程终止。
Do I need to have a variable to store the NetworkMonitor() instance in the service, or can I just have an anonymous instance like this?
您需要有一个实例,以便稍后可以取消注册。接收者的注册和注销应由服务完成;你的 register-the-receiver-in-its-constructor 是使你的代码变得可怕的部分原因。
Looking at the docs the BroadcastReceiver should clear itself up after onReceive() has finished
list 注册的 BroadcastReceiver
为单个广播而存在。通过 registerReceiver()
注册的 BroadcastReceiver
会一直存在,直到 unregisterReceiver()
。
Why do I need NetworkMonitor.mDoingStuff?
你有更大的问题。
Is this a sensible way of doing this
不完全是。
首先,您将在第二次广播时崩溃,因为您无法多次 execute()
AsyncTask
实例。
其次,请参阅前面提到的无法取消注册的问题。
第三,如果您想要一个服务只做一件事,然后就消失,请使用 IntentService
。
那么,让我们一路回到顶部:
I have an app in which I want to perform lookup some data every, say, 15 mins. I have a service that I start with an alarm, but I also want to make sure that there is a network connection before I start looking.
正确的做法是:
将您的 AlarmManager
事件路由到 BroadcastReceiver
。如果您使用 _WAKEUP
警报类型,这一点尤其重要,因为只有使用 BroadcastReceiver
PendingIntent
时,此类事件才可靠。
在 BroadcastReceiver
中,在 onReceive()
中,如果您有网络连接,请向 IntentService
发送命令以完成这项工作(并且,如果您使用 _WAKEUP
闹钟类型,请考虑我的 WakefulIntentService
,以便设备在您执行此操作时保持唤醒状态)。
如果似乎没有网络连接,请让您的 BroadcastReceiver
启用另一个 list 注册的 BroadcastReceiver
设置来监视 CONNECTIVITY_ACTION
事件 - 为此使用 PackageManager
和 setComponentEnabledSetting()
。
在CONNECTIVITY_ACTION
BroadcastReceiver
中,在onReceive()
中,如果您确定现在有网络连接,请启动您的 IntentService
(如果您已建立连接,则与您在 AlarmManager
接收器中执行的操作相同)。
在IntentService
/WakefulIntentService
中,在onHandleIntent()
中完成您的工作。它已经有一个后台线程,并且当没有更多工作要做时就会调用 stopSelf()
。
在 IntentService
/WakefulIntentService
的 onDestroy()
中,禁用 CONNECTIVITY_ACTION
BroadcastReceiver
通过 PackageManager
和 setComponentEnabledSetting()
,将您返回到原始状态。
这样:
您不会泄漏内存,就像您在这里所做的那样。
您不必像在这里那样弄乱线程代码。
您不必担心在警报和获得连接之间您的进程是否会被踢出内存。
如果连接被阻止一段时间(例如,飞行模式),您无需像此处那样注册 N 个接收器并设置 N 个 AsyncTasks
。相反,当闹钟响起后,只要将来连接发生变化,您就可以再次获得控制权。
关于java - BroadcastReceiver 意外调用了 onReceive(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16288901/
我的应用程序无法在 Android 7 上运行。调用了我的 BroadcastReceiver.onReceive 方法,但缺少 intent.getExtras 的内容。我已验证数据已正确加载。这是
我认为即使我退出应用程序,BroadcastReceiver AlarmManagerBroadcastReceiver 也会继续运行。我认为 BroadcastReceiver 会在我重新启动系统时
我为 Wi-Fi 创建了一个 brodcastReceiver,一切正常,除了,当我午餐应用程序时,broadcastreceiver 开始直接扫描,我无法停止它,即使我离开应用。我试图从主要 Act
我最近开始在我的 Android 应用程序上使用 Google Analytics(分析)。我想知道如何在 BroadcastReceiver 的 onReceive 方法中将事件发送到 GA。这是一
我想在 Broadcast Receiver 中检查互联网连接;并将结果( bool 标志)设置为全局变量,以便在 if 条件下将其用于整个应用程序;如果互联网断开连接,则在主要 Activity 中
如果用户向上或向下按下音量键,是否可以在我的广播接收器中检测到它?我需要完整的代码。 这是我的 Intent 过滤器 IntentFilter filter = new IntentFilter();
我正在尝试编写一个应用程序,其中我根据使用 gcm 推送通知发送的消息对 UI 进行更改,并且我设法通过使用 BroadcastReceiver onReceive 函数来实现它来实现它,但它仅在应用
我正在尝试使用 AlarmManager 安排通知当我安排一个通知时它工作得很好,但是当我安排两个通知时,第一个通知没问题,但第二个通知不起作用。 我发现几分钟后打开应用程序会通知第二个通知。我认为我
我正在阅读指南 here关于设置 BroadcastReceiver 来检查电池变化。它指出我可以像这样设置一个 BroadcastReceiver:
我想在应用程序中接收有关启用/禁用位置提供程序的信息,例如NETWORK、GPS等。我创建了简单的BroadcastReceiver: public class TestReciver extends
我正在使用广播接收器来设置警报警报,但由于某种原因它无法工作。 public class SimpleSleepActivity extends Activity { /** Called when
当我的应用程序处于后台时,我尝试播放一些音调,并按下“相机”按钮,因为我正在执行此简单的步骤。 创建BroadcastReceiver类 public class CameraButtonListen
我创建了我的广播接收器 AnprEventReciever,它应该在连接状态发生变化时被触发,但它并没有。 事件接收者: import android.content.BroadcastReceive
我有一个时间选择器来设置闹钟 public class TimePickerFragment : DialogFragment, TimePickerDialog.IOnTimeSetListener
我目前正在开发一个使用 broadcastreceiver 来检查收到的短信的应用程序,但突然间它似乎停止工作了,我什至写了一个小的测试应用程序,以至少对我来说,语法上似乎是正确的,但也不起作用。 这
我正在尝试使用 BroadcastReceiver 获取互联网连接状态。 接收类是这样的: public class ConnectivityReceiver extends BroadcastRec
我有一个小部件,它只使用服务来更新小部件的 RemoteView 的外观。该服务基于由不同注册的 BroadcastReceiver 提供的过滤器启动。当满足其中一个条件时,将调用我的 Broadca
我没有时间玩接收器,而且我对2.3.x以上的东西都不熟悉,所以当我读到这个问题时,我感到非常困惑: Can BroadcastReceiver registered in AndroidManifes
我有一个录音机 android 线程,我需要知道录音时麦克风/耳机是否已连接,所以我需要在线程内使用 BroadcastReceiver()。我如何注册它? this.registerReceiver
大家好,感谢您的帮助!我将从代码开始 所以,带有广播接收器的类是这样的: public class MyService extends Service { // ... // ACTI
我是一名优秀的程序员,十分优秀!