Подтвердить что ты не робот

Как начать новую тему в сервисе?

Я разрабатываю приложение для Android, и я выполняю тяжелую работу (принося информацию с веб-страницы в Интернете и анализируя ее для хранения в базе данных) в службе. В настоящее время он занимает около 20+ минут, и за это время мой пользовательский интерфейс застрял. Я думал использовать поток в сервисе, поэтому мой пользовательский интерфейс не застревает, но он дает ошибку. Я использую следующий код:

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, он все равно не работает. Пожалуйста, может кто-нибудь сказать мне, какую ошибку я делаю. Видимо, я скопировал этот код непосредственно из электронной книги. Это должно работать, но его нет.

4b9b3361

Ответ 1

Пример создания нового потока, взятого из образцов 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

Android-заповедник: вы не должны взаимодействовать с объектами пользовательского интерфейса из ваших собственных потоков

Оберните дисплей Toast в runOnUIThread(new Runnable() { });

Ответ 3

Вы можете использовать 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

Вы можете определить свои задания в запущенном объекте, использовать объект потока для его запуска и запустить этот поток в своей службе onStartCommand(). Вот мои заметки:

В вашем классе обслуживания:

  • определить основной цикл в объекте Runnable
  • создать объект Thread с помощью объекта runnable в качестве параметра

В вашем классе обслуживания onStartCommand method():

  • вызов функции запуска объекта потока()

мой код:

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