开发者

How to start a new Thread in a service?

I am 开发者_如何学Cdeveloping 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:

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.


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

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


Example of new thread creation taken from Android samples (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.


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

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


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:

In your service class:

  1. define your main loop in an Runnable object
  2. create Thread object with the runnable object as parameter

In your service class's onStartCommand method():

  1. call thread object's start function()

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜