#android #multithreading #service
#Android #многопоточность #Обслуживание
Вопрос:
public class TestService extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final Intent service=new Intent(getApplicationContext(),MessageListener.class);
Log.v("Test", "Going to start service");
startService(service);
Log.v("Test", "service started?");
}
}
public class MessageListener extends Service {
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.v("Test", "Start Cmd");
intent.setAction("Started");
new Thread(new Runnable() {
@Override
public void run() {
for(int i=100;i<200;i ){
Log.v("Test",i "");
}
}
}).start();
return START_STICKY;
}
@Override
public void onCreate() {
super.onCreate();
Log.v("Test", "Create");
}
Я ожидаю, что это напечатает:
Start Service
create
Start cmd
print 1->100
Service Started.
Но я получаю
Start Service
Service Started.
create
Start cmd
prints 1->100
Почему это?
Я обнаружил, что проблема связана с асинхронностью. startService будет вызван после завершения родительского метода. Решение заключается:
public class TestService extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Intent service=new Intent(getApplicationContext(),MessageListener.class);
startService(service);
mCheckerHandler.sendEmptyMessageDelayed(MSG_CHECK_SERVICE_RUNNING, 100);
}
private static final int MSG_CHECK_SERVICE_RUNNING = 0x001122;
private Handler mCheckerHandler = new Handler() {
public void handleMessage(android.os.Message msg) {
if (msg.what == MSG_CHECK_SERVICE_RUNNING) {
if (checkServiceRunning()) {
//Do something
} else {
//Send another message to check in the next 100ms
sendEmptyMessageDelayed(MSG_CHECK_SERVICE_RUNNING, 100);
}
}
};
};
}
Спасибо за всех вас. Особенно для мистера Биня 🙂
Комментарии:
1. Не понял, чего вы ожидаете и что получаете?
2. Вы вообще не получили
Service started
?3. Да, я это сделал, это после запуска службы
Ответ №1:
Это потому, что поток выполняется «псевдо»-параллельно, поэтому Log.v("Test", "service started?");
вызывается до того, как встречный поток получит время процессора для записи.
«Псевдо» -параллельный, потому что у большинства телефонов не более 1 процессора, поэтому они не могут вычислять параллельно, поэтому они переключаются только с одного потока на другой. Вы можете прочитать больше о потоковой обработке в Википедии или любом другом источнике, который вам нравится.
Комментарии:
1. Проблема по-прежнему возникает, когда я не использую поток. В документе Android говорится, что служба будет выполняться в том же процессе, что и основное действие. Я думал, что это будет печатать по порядку?
2. Но в документации также говорится, что «Метод startService() возвращается немедленно, и система Android вызывает метод onStartCommand() службы» . 😉
3. @alopix — вы имеете в виду, какая служба запускается в том же процессе и в том же потоке, что и действие, которое инициирует запуск службы???
4. @Olegas Служба Android запускается и выполняется в основном процессе приложения (если не указано иное). И поскольку она не создает новый поток, она будет выполняться в основном потоке приложения.