我有点困惑什么是使用Service的正确位置(用于后台任务)。
这是我的情景:
我有一个扩展广播接收器的类。它接收WiFi状态变化。根据状态的变化,我打电话给另一个班级。这是一个纯Java类,不扩展任何类。
通过传递Context
(与广播接收器一起接收)来实例化该类。
我需要传递Context
,因为除其他外,我访问SharedPreferences
,显示通知等。但这不是前台活动。
这是正确的方法吗?或者我的班级应该扩展Service
并作为后台任务工作吗?
传递Context
来启动课程是错误的吗?
例如,
public class WifiStateBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
...
WifiChangeReceptionClass wifiChanged = new WifiChangeReceptionClass(context);
wifiChanged.showNotification();
...
}
这种方法有什么问题?
答案 0 :(得分:2)
尝试以下任何一项:
public class MyApplication extends Application {
...
public static MyApplication get(){
return this;
}
...
}
或者
创建一个具有静态方法的Application类来获取它的上下文,就像这样。
public class WifiChangeReceptionClass{
public static void showNotification(){
Context context = MyApplication.get();
//showYourNotification
}
}
然后在你的课堂上,请致电:
filename_format = prefix + startdate.strftime('%Y%m%d') + '_' + enddate.strftime('%Y%m%d')
LOGGER.info('Filename format: ' + filename_format)
或者
只需使用匕首进行依赖性注射。 Check docs here
答案 1 :(得分:1)
这是错误的,因为只要您在onReceive()方法中,上下文引用就可用。一旦回调onReceive()方法获得完成,上下文将不再可用。
答案 2 :(得分:1)
只要您在广播接收器的生命周期内使用上下文(您可以将其传递给任何类),这绝对没问题。由于广播接收器和服务都在UI线程上运行,因此使用服务不会产生太大的影响。
如果要执行某些网络操作或长时间运行操作,则可以从接收器实例化意图服务。
答案 3 :(得分:1)
注册广播接收器以获取Wifi状态更改可能不会来自Android 7它已禁用CONNECTIVITY_CHANGED。
针对Android 7.0(API级别24)及更高版本的应用如果在其清单中声明广播接收器,则不会收到CONNECTIVITY_ACTION广播。如果应用程序使用Context.registerReceiver()注册其BroadcastReceiver并且该上下文仍然有效,则仍会收到CONNECTIVITY_ACTION广播。
这包括连接更改。更好的选择是使用JobScheduler。请参阅此link
如响应中所述,BroadcastReceiver的onReceive()在主线程上执行。基于android documentation广播接收器
作为一般规则,广播接收机允许运行最多 10秒,然后系统才会认为它们无响应且ANR应用。由于这些通常在应用程序的主线程上执行,因此它们已经受到可能发生的各种操作的约5秒时间限制(更不用说仅仅避免UI jank),因此接收限制通常不受关注。但是,一旦你使用goAsync,虽然能够脱离主线程,广播执行限制仍然适用,包括调用此方法和最终PendingResult.finish()之间所花费的时间。
如果您的WifiChangeReceptionClass正在做一些大量工作,那么请不要直接在onRecevie()中运行。而是启动Service(您必须生成一个新的线程线程)或IntentService