Я пытаюсь создать простую программу для Android, которая тянет веб-сервер каждые 30 * 1000 миллисекунд. В моем приложении есть выделенный сервис - PollerService
Android Manifest.xml:
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".PullServerAndListenActivivty"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".PollerService" />
</application>
Класс создает запланированного исполнителя и регистрирует его задачу таймера, чтобы начать вызывать Механизм, который в порядке вытягивает сервер.
PollerService.java:
public class PollerService extends Service {
public static final int INTERVAL = 20*1000;
private ScheduledExecutorService executor;
public void onCreate() {
super.onCreate();
executor = Executors.newSingleThreadScheduledExecutor();
executor.scheduleAtFixedRate(new TimerTask() {
public void run() {
Engine.tick ();
}
}, 0, INTERVAL, TimeUnit.MILLISECONDS);
}
public void onDestroy() {
executor.shutdownNow();
}
public IBinder onBind(Intent arg0) {
return null;
};
}
Механизм просто создает экземпляр подкласса AsyncTask в потоке GUI и выполняет его. onPostExecute записывает строку через консоль, которая была назначена в Activity, и вызывает компоненты пользовательского интерфейса.
public class Engine {
private static Console console; //Assigned in Activity onCreate
private static Activity context;//Assigned in Activity onCreate
...
public static void tick() {
final String requestURL = String.format(urlFormat, serverURL);
try {
context.runOnUiThread(
new Runnable () {
public void run() {
new RequestTask().execute(requestURL);
};
}
);
}
catch (Throwable e) {
Log.e("SBOX", e.getMessage(), e);
}
}
public static void processCommand(String result) {
try {
final Command command = fromJSONToCommand(result);
context.runOnUiThread(new Runnable() {
public void run() {
console.writeLine("Receieved command: " + command);
}
});
} catch (Exception e) {
Log.e ("SBOX", e.getMessage(), e);
}
}
Як, я начал с простого создания экземпляра RequestTask, у меня сложилось впечатление, что он будет работать в потоке пользовательского интерфейса, но, пытаясь решить проблему, я, наконец, пришел к такому подходу, все еще бесполезному. Просто хочу сказать, что я много пробовал здесь.
RequestTask выглядит следующим образом, простой вызов http:
class RequestTask extends AsyncTask<String, Void, String>{
@Override
protected String doInBackground(String... uri) {
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response;
String responseString = null;
try {
response = httpclient.execute(new HttpGet(uri[0]));
StatusLine statusLine = response.getStatusLine();
if(statusLine.getStatusCode() == HttpStatus.SC_OK){
ByteArrayOutputStream out = new ByteArrayOutputStream();
response.getEntity().writeTo(out);
out.close();
responseString = out.toString();
} else{
response.getEntity().getContent().close();
throw new IOException(statusLine.getReasonPhrase());
}
} catch (Exception e) {
Log.e("SBOX", e.getMessage(), e);
}
return responseString;
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
Engine.processCommand (result);
}
}
Так что проблема в том, что он работает правильно только один раз, таймер планирует, вызывает первый раз Engine, он запускает RequestTask, он тянет сервер, получает ответ, печатает его в консоли. Но второй раз он попадает в метод таймера, и тогда никаких признаков жизни со стороны сервиса. Нет исключений в LogCat, вход в RequestTask не печатается.
Конечно, пришло время отладки, но, возможно, кто-то может спасти меня от этой боли и показать ошибки в коде? Сам исполнитель работает идеально непрерывно, если комментировать вызов Engine.tick ().
Будет очень благодарен за подсказки по разрешению.