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