如何在服务中启动新线程?

时间:2010-11-14 17:29:43

标签: android

我正在开发一个Android应用程序,我正在做一些繁重的工作(将数据从在线网页中解析并将其解析为存储在数据库中)。目前,它需要大约20多个分钟,而这一次我的UI被卡住了。我正在考虑在服务中使用一个线程,所以我的UI不会卡住,但它会给出错误。我使用以下代码:

Thread thread = new Thread()
{
      @Override
      public void run() {
          try {
              while(true) {
                  sleep(1000);
                  Toast.makeText(getBaseContext(), "Running Thread...", Toast.LENGTH_LONG).show();
              }
          } catch (InterruptedException e) {
           Toast.makeText(getBaseContext(), e.toString(), Toast.LENGTH_LONG).show();
          }
      }
  };

thread.start();

这个简单的代码给出了运行时错误。即使我取出while循环,它仍然无法正常工作。 拜托,任何人都可以告诉我我在做什么错。显然,我直接从电子书中复制了这段代码。它可以起作用但不是。

4 个答案:

答案 0 :(得分:41)

Android诫命:您不得与自己的线程中的UI对象进行交互

将您的Toast Display包装到runOnUIThread(new Runnable() { });

答案 1 :(得分:34)

从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;
}

runnable是包含网络操作的Runnable。

答案 2 :(得分:12)

你可以使用HandlerThread并发布到它,这是一个有一个服务的例子。

public class NetworkService extends Service {

    private HandlerThread mHandlerThread;
    private Handler mHandler;
    private final IBinder mBinder = new MyLocalBinder();

    @Override
    public void onCreate() {
        super.onCreate();

        mHandlerThread = new HandlerThread("LocalServiceThread");
        mHandlerThread.start();

        mHandler = new Handler(mHandlerThread.getLooper());
    }

    public void postRunnable(Runnable runnable) {
        mHandler.post(runnable);
    }

    public class MyLocalBinder extends Binder {
        public NetworkService getService() {
            return NetworkService.this;
        }
    }

    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }
}

答案 3 :(得分:3)

您可以在可运行的对象中定义作业,使用线程对象运行它,并在服务的onStartCommand()函数中启动此线程。这是我的笔记:

在您的服务类中:

  1. Runnable对象
  2. 中定义主循环
  3. 使用runnable对象创建Thread对象作为参数
  4. 在服务类的onStartCommand方法()中:

    1. 调用线程对象的启动函数()
    2. 我的代码:

      private Runnable busyLoop = new Runnable() {
          public void run() {
              int count = 1;
              while(true) {
                  count ++;
                  try {
                      Thread.sleep(100);
                  } catch (Exception ex) {
                      ;
                  }
                  ConvertService.running.sendNotification("busyLoop" + count);                      
              }
          }
      };
      
      public int onStartCommand(Intent intent, int flags, int startId) {
          sendNotification("onStartCommand");
          if (! t.isAlive()) {
              t.start();
          }
          return START_STICKY;
      }