何时扩展服务并在后台运行

时间:2018-03-26 13:16:49

标签: android background-process android-context

我有点困惑什么是使用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();
...
}

这种方法有什么问题?

4 个答案:

答案 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