我有一个启动newSingleThreadScheduledExecutor()
的服务。
因此,所有完成的工作都是在工作线程中完成的。
在线程中做的是,从服务器检索一个值,做一些简单的计算并在SharedPreference中保存一个值。
很少,我得到ANR,而log logage告诉我服务造成的 你知道它为什么会发生吗?
此外,如果重要,我有时会重新启动我的服务(停止它,在ScheduledExecutorService
上调用shutdownNow(),然后重新启动它。)
这是代码的相关部分。
public void onCreate() {
sharedPreferences = getSharedPreferences(Constant.SHARED_PREFERENCE, MODE_PRIVATE);
broadcaster = LocalBroadcastManager.getInstance(this);
registerReceiver();
if(scheduler == null) {
scheduler = Executors.newSingleThreadScheduledExecutor();
scheduler.scheduleWithFixedDelay
(new Runnable() {
public void run() {
android.util.Log.d(TAG, "globalLogic Scheduler started");
globalLogic();
}
}, 0, CHECK_PERIOD, TimeUnit.HOURS);
}
}
答案 0 :(得分:0)
您应该照顾好Service
,因为Service
通常会在UIThread
中运行:
警告:服务在其托管进程的主线程中运行;除非另行指定,否则服务不会创建自己的线程,也不会在单独的进程中运行。如果您的服务要执行任何CPU密集型工作或阻止操作(如MP3播放或网络),则应在服务中创建新线程以完成该工作。通过使用单独的线程,您可以降低应用程序无响应(ANR)错误的风险,并且应用程序的主线程可以保持专用于用户与您的活动的交互。
有3种方法可以解决您的问题:
IntentService
Service
或者让您的Service
在不同的流程中运行,如下所示:
<service
android:name="com.example.appName"
android:process=":externalProcess"/>
如果分配给此属性的名称以冒号(&#39;:&#39;)开头,则在需要时创建一个专用于应用程序的新进程,并且该服务在该进程中运行处理。如果进程名称以小写字符开头,则服务将在该名称的全局进程中运行,前提是它具有此权限。这允许不同应用程序中的组件共享进程,从而减少资源使用。
您可以阅读有关服务Here
的更多信息答案 1 :(得分:0)
尝试在ExecutorService
中使用更多主题:
scheduler = Executors.newFixedThreadPool(3);
答案 2 :(得分:0)
为什么你不使用像Firebase JobDispatcher这样的东西? 它效率高,支持API级别9 +。
唯一的限制是它依赖于Google Play服务。
<强>要求强>: FirebaseJobDispatcher当前依赖于Google Play服务中的计划组件。因此,它不适用于未安装Google Play服务的环境。