android-如何在与主线程不同的线程中运行服务?
Posted
技术标签:
【中文标题】android-如何在与主线程不同的线程中运行服务?【英文标题】:android-How to run Service in different thread than main thread? 【发布时间】:2013-11-02 14:50:43 【问题描述】:我正在尝试在 android 中开发一个应用程序,该应用程序包含一个读取传感器值多个小时的服务。当我启动服务时,我的设备挂起,所有其他进程都变慢了。为了解决这个问题,我尝试在单独的线程中启动服务,如下所示,但问题仍然存在。
new Thread(new Runnable()
@Override
public void run()
Intent intent=new Intent(getApplicationContext(), SensorService.class);
startService(intent);
).start();
这个线程只在不同的线程中启动服务,但服务在主线程中运行。 请有人帮助我如何在单独的线程中运行服务?
【问题讨论】:
您应该发布您尝试运行的代码,以便我们可以准确地看到您在做什么。我的猜测是您在服务中拥有的代码应该在新线程上执行。请发布您尝试执行的服务。 【参考方案1】:应用程序组件(服务、活动等)始终在主线程中运行,无论它们是从哪个线程启动的。
请考虑在您的服务中启动线程,或使用IntentService
。
在您的特定情况下,您可能会尝试为传感器更改注册一个全局 BroadcastReceiver
,这反过来又会启动一个 IntentService
以将新获取的值放入 db 等中。
其实here is the link类似的问题已经解决了。
同样,这并不是真正的多线程问题。整个任务必须以另一种方式实现。
【讨论】:
嗨尤金,感谢您的快速回复。传感器值每 70 毫秒变化一次,所以我认为我们不需要注册一个全球广播接收器。 恐怕长时间运行的任务在 70 毫秒注册事件会很快耗尽电池。 IntentService 现已弃用【参考方案2】:您可以使用后台服务来解决这个问题。通过在特定情况下使用Thread
和sleep()
可以解决您的问题
Background Servies
这个链接会帮助你..
或者使用PendingIntent
会帮助你,比如...
PendingIntent operation = PendingIntent.getActivity(getBaseContext(), 0, ij, Intent.FLAG_ACTIVITY_NEW_TASK);
【讨论】:
【参考方案3】:您所做的只是启动新活动,因此如果您运行监视器的逻辑位于SensorService
中,那么它仍将位于主线程上。您需要将监控逻辑放入新线程中,而不仅仅是使用它启动活动。
如果您尝试在后台线程上运行服务,则需要使用静态 performOnBackgrounThread
方法,如可在 Android 文档 (android-8\SampleSyncAdapter\src\com\example\android \samplesync\client\NetworkUtilities.java):
public static Thread performOnBackgroundThread(final Runnable runnable)
final Thread t = new Thread()
@Override
public void run()
try
runnable.run();
finally
;
t.start();
return t;
同样重要的是要记住,您永远不想在主 UI 线程上执行网络操作。不是你在这里,只是一个仅供参考......
【讨论】:
嗨 Blaine,如何将监控逻辑放在新线程中。? 您提供的代码不起作用.. 服务仍在主线程中运行。我想在不同的线程中运行.. 您应该发布您尝试运行的代码,以便我们可以准确地看到您在做什么。【参考方案4】:我认为这个问题的答案在于IntentService
的力量。 IntentService 是常规 Service 类的子类。但是,有一些关键的区别。
现在,您可以通过以下方式利用 IntentServices:IntentServices 不在主线程上运行。相反,它们在单独的“工作线程”上运行。这个单一属性将解决您的问题并消除您当前面临的 ANR。
要详细了解服务和 IntentServices 之间的区别,check this out。
【讨论】:
【参考方案5】:您可以尝试使用AsyncTask
,请阅读此文档。
http://developer.android.com/reference/android/os/AsyncTask.html
【讨论】:
这对我不起作用;尽管对startService
的调用是在不同的线程中完成的,但该服务似乎仍在主线程中运行。【参考方案6】:
要在同一个进程但另一个非主线程中启动服务,我们可以创建另一个HandlerThread
并使用Handler
在其上运行我们的作业。
class MyService : Service()
private lateinit var thread: HandlerThread
private lateinit var handler: Handler
override fun onCreate()
super.onCreate()
thread = HandlerThread("MyService").apply
start()
handler = Handler(thread.looper)
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int
if (intent?.action == "my-job")
handler.post
// Do any job on another non-main thread here
// ...
override fun onDestroy()
thread.interrupt()
super.onDestroy()
【讨论】:
以上是关于android-如何在与主线程不同的线程中运行服务?的主要内容,如果未能解决你的问题,请参考以下文章