【发布时间】:2017-09-11 17:47:41
【问题描述】:
我目前正在使用 Firebase JobDispatcher 使用服务意图在后台运行定期检查(在启动、安装和更新时注册)。这工作正常,它产生了与主线程分开的自己的线程,所以我没有锁定 UI,它正确地终止了线程,所以垃圾收集不会成为问题。
我还想从应用内的主线程触发同样的工作。问题是运行 jobdispatcher onCreate 会触发作业在主 UI 线程中运行,而不是在后台线程中运行。我的一个函数可以生成很多对象,所以即使它正常运行,它也会破坏应用程序的可用性,因为 GC 永远无法摆脱所有垃圾。
如何从主线程按需运行现有的 JobDispatcher 作业,但仍然在单独的线程中?
非常感谢您的帮助。
为澄清此特定用途而进行的编辑
我的特殊情况涉及第一次运行,其中 UpdateNetworkerJob.class 可能需要几分钟才能运行。 phoneHistoryCheck.GetLastCallChecked() 函数有一个循环,可以多次调用 Firebase,检索和放置信息。
9/12 更新
后续运行非常快,AsyncTask 可以工作。但是我发现我需要一个更强大的解决方案,目前正在查看ThreadPoolExecutor。有可能 GetLastCallChecked() 函数在 Firebase 引擎上抛出了太多东西,并导致主线程对 Firebase 的调用在赶上的噪音中下降。我正在整理这部分。
在主线程中开始工作的代码:
FirebaseJobDispatcher dispatcher = new FirebaseJobDispatcher(new GooglePlayDriver(trackedContactListActivity.this));
Job myJob = dispatcher.newJobBuilder()
.setService(UpdateNetworkerJob.class)
.setTag("UpdateNetworkerService")
.setTrigger(Trigger.NOW)
.setConstraints(
Constraint.ON_ANY_NETWORK
)
.build();
dispatcher.mustSchedule(myJob);
UpdateNetworkerJob.class
public class UpdateNetworkerJob extends JobService {
private static final String TAG = "UpdateNetworkerJob";
@Override
public boolean onStartJob(final JobParameters params) {
Log.d(TAG, "UpdateNetworkerJob is running with params: " + params);
PhoneHistoryCheck phoneHistoryCheck = new PhoneHistoryCheck();
phoneHistoryCheck.GetLastCallChecked(UpdateNetworkerJob.this);
return false;
}
@Override
public boolean onStopJob(JobParameters params) {
// Stop tracking these job parameters, as we've 'finished' executing.
//sendMessage(MSG_COLOR_STOP, params.getJobId());
Log.d(TAG, "on stop job: " + params);
// Return false to drop the job.
return false;
}
}
【问题讨论】:
-
你的帖子说:这工作正常,它产生了它自己的线程。那是指
UpdateNetworkerJob吗?我看不到它在哪里创建工作线程。您还声明:问题是运行 jobdispatcher onCreate 会触发作业在主 UI 线程中运行,而不是在后台线程中运行。调度的作业是JobService,它在主线程上运行,不管调度它的线程是什么。您必须创建自己的 JobService 工作线程。见:intro to the JobService docs -
正确。我的扩展广播接收器的类不包含在原始问题中。我运行了一个类似的 FirebaseJobDispatcher,但它在清单中的意图下注册:BOOT_COMPLETED、PACKAGE_REPLACED、PACKAGE_ADDED。以这种方式运行时,我可以看到我的应用程序的一个单独线程在 Android 监视器中生成并终止。您指出的那些文档提到需要卸载工作的“线程/处理程序/AsyncTask”。你是这个意思吗?所以这遵循下面的逻辑——我需要以某种方式手动启动一个单独的线程。感谢您的帮助。
-
您可以使用
Thread.currentThread().getName()获取线程名称。将其添加到来自UpdateNetworkerJob的一些日志输出中。我非常有信心它将成为主/ UI 线程,即使是从您的 BroadcastReceiver 启动的。是的,您需要返工UpdateNetworkerJob以在工作线程或 AsyncTask 中执行长时间处理。 -
啊...好的。会检查的。因此,仅在 Android Monitor 中看到第二个线程 ID 并不能保证它实际上是独立的?抱歉,我显然对此很陌生。非常感谢您的帮助!
-
我不知道第二个线程是什么。很确定这不是你的 JobService。
标签: android multithreading firebase firebase-job-dispatcher