25

我正在尝试在 android 中开发一个应用程序,该应用程序包含一个读取传感器值多个小时的服务。当我启动服务时,我的设备挂起,所有其他进程都变慢了。为了解决这个问题,我尝试在单独的线程中启动服务,如下所示,但问题仍然存在。

    new Thread(new Runnable() {

                @Override
                public void run() {
                    Intent intent=new Intent(getApplicationContext(), SensorService.class);
                    startService(intent);

                }
            }).start();

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

4

6 回答 6

9

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

在您的特定情况下,您可能会尝试BroadcastReceiver为传感器更改注册一个全局变量,这反过来将开始IntentService将新获取的值放入数据库等。

实际上,这是解决类似问题的链接。

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

于 2013-10-24T04:32:40.927 回答
2

你所做的只是启动新的活动,所以如果你运行监视器的逻辑是 in 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 线程上执行网络操作。不是你在这里,只是一个仅供参考......

于 2013-10-24T04:29:46.120 回答
2

您可以使用后台服务来解决此问题。通过使用Threadwithsleep()来解决你的问题

后台服务

这个链接会帮助你..

或者使用 ofPendingIntent会帮助你,比如......

PendingIntent operation = PendingIntent.getActivity(getBaseContext(), 0, ij, Intent.FLAG_ACTIVITY_NEW_TASK);
于 2013-10-24T04:46:14.197 回答
1

我认为这个问题的答案在于IntentService. IntentService 是常规 Service 类的子类。然而,有一些关键的区别。

现在,您可以通过以下方式利用 IntentServices:IntentServices 不在主线程上运行。相反,它们在单独的“工作线程”上运行。这个单一属性将解决您的问题并消除您当前面临的 ANR。

要了解有关服务和 IntentServices 之间差异的更多信息,请查看此内容。

于 2019-10-21T00:25:27.640 回答
0

您可以尝试使用AsyncTask,请阅读此文档。

http://developer.android.com/reference/android/os/AsyncTask.html

于 2013-10-24T04:31:32.113 回答
0

要在同一个进程但另一个非主线程中启动服务,我们可以创建另一个HandlerThreadHandler用于在其上运行我们的作业。

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()
    }
}
于 2022-01-27T01:31:25.980 回答