【问题标题】:android-How to run Service in different thread than main thread?android-如何在与主线程不同的线程中运行服务?
【发布时间】: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();

这个线程只在不同的线程中启动服务,但服务在主线程中运行。 请有人帮助我如何在单独的线程中运行服务?

【问题讨论】:

  • 您应该发布您尝试运行的代码,以便我们可以准确地看到您在做什么。我的猜测是您在服务中拥有的代码应该在新线程上执行。请发布您尝试执行的服务。

标签: android multithreading


【解决方案1】:

应用程序组件(服务、活动等)始终在主线程中运行,无论它们是从哪个线程启动的。 请考虑在您的服务中启动线程,或使用IntentService

在您的特定情况下,您可能会尝试为传感器更改注册一个全局 BroadcastReceiver,这反过来又会启动一个 IntentService 以将新获取的值放入 db 等中。

其实here is the link类似的问题已经解决了。

同样,这并不是真正的多线程问题。整个任务必须以另一种方式实现。

【讨论】:

  • 嗨尤金,感谢您的快速回复。传感器值每 70 毫秒变化一次,所以我认为我们不需要注册一个全球广播接收器。
  • 恐怕长时间运行的任务在 70 毫秒注册事件会很快耗尽电池。
  • IntentService 现已弃用
【解决方案2】:

您可以使用后台服务来解决这个问题。通过在特定情况下使用Threadsleep() 可以解决您的问题

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()
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-09-02
        • 1970-01-01
        • 2012-02-17
        • 2011-04-29
        • 1970-01-01
        • 2023-03-05
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多