0

我目前正在使用 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;
}
}
4

2 回答 2

0

doinBackgroundAsynctask. 示例在这里:Asynctask文档

您可以Asynctask从 UI 控制结果,而无需按住 UI 来获取结果。

于 2017-09-11T18:14:05.823 回答
0

AsyncTask里面的东西可以运行多长时间没有限制?第一次在我的应用程序中运行它们可以运行几分钟。

您可以在线程性能文章中找到您的查询的答案。

使用 AsyncTask 时,需要牢记几个重要的性能方面。

首先,默认情况下,应用程序会将其创建的所有 AsyncTask 对象推送到单个线程中。因此,它们以串行方式执行,并且与主线程一样,特别长的工作包会阻塞队列。因此,我们建议您只使用 AsyncTask处理持续时间小于 5 毫秒的工作项

HandlerThreadThreadPoolExecutor提供了其他选择。

HandlerThread您可以在这篇文章中找到示例代码:

从Android中的辅助线程调用主线程

于 2017-09-12T11:16:24.397 回答