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

时间:2020-11-28 20:38:59

I am developing an Android app and I am doing some heavy work (bringing data from an online web page and parsing it to store in database) in a service. Currently, it is taking about 20+ mins and for this time my UI is stuck. I was thinking of using a thread in service so my UI doesn't get stuck but it is giving error. I am using the following code:

我正在开发一个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();

This simple code is giving run time error. Even If I take out the while loop, it is still not working. Please, can any one tell me what mistake I am doing. Apparently, I copied this code directly from an e-book. It is suppose to work but its not.

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

4 个解决方案

#1


34  

Example of new thread creation taken from Android samples (android-8\SampleSyncAdapter\src\com\example\android\samplesync\client\NetworkUtilities.java):

从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 is the Runnable that contains your Network operations.

runnable是包含网络操作的Runnable。

#2


41  

Android commandment: thou shall not interact with UI objects from your own threads

Android命令:你不能与自己的线程中的UI对象进行交互

Wrap your Toast Display into runOnUIThread(new Runnable() { });

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

#3


11  

You can use HandlerThread and post to it, here is an example to service that has one.

您可以使用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;
    }
}

#4


2  

You may define your jobs in a runnable object, use a thread object for running it and start this thread in your service's onStartCommand() function. Here is my notes:

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

In your service class:

在您的服务类中:

  1. define your main loop in an Runnable object
  2. 在Runnable对象中定义主循环

  3. create Thread object with the runnable object as parameter
  4. 使用runnable对象作为参数创建Thread对象

In your service class's onStartCommand method():

在服务类的onStartCommand方法()中:

  1. call thread object's start function()
  2. 调用线程对象的启动函数()

my code :

我的代码:

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

#1


34  

Example of new thread creation taken from Android samples (android-8\SampleSyncAdapter\src\com\example\android\samplesync\client\NetworkUtilities.java):

从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 is the Runnable that contains your Network operations.

runnable是包含网络操作的Runnable。

#2


41  

Android commandment: thou shall not interact with UI objects from your own threads

Android命令:你不能与自己的线程中的UI对象进行交互

Wrap your Toast Display into runOnUIThread(new Runnable() { });

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

#3


11  

You can use HandlerThread and post to it, here is an example to service that has one.

您可以使用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;
    }
}

#4


2  

You may define your jobs in a runnable object, use a thread object for running it and start this thread in your service's onStartCommand() function. Here is my notes:

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

In your service class:

在您的服务类中:

  1. define your main loop in an Runnable object
  2. 在Runnable对象中定义主循环

  3. create Thread object with the runnable object as parameter
  4. 使用runnable对象作为参数创建Thread对象

In your service class's onStartCommand method():

在服务类的onStartCommand方法()中:

  1. call thread object's start function()
  2. 调用线程对象的启动函数()

my code :

我的代码:

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