私は30 * 1000ミリ秒ごとにWebサーバーをプルする簡単なAndroidプログラムを作成しようとしています。私は自分のアプリケーションにサービスを捧げて - PollerServiceAndroidサービスでスケジュールされたAsynTaskは1回だけ正しく実行されます
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>
クラスが予定さexecutorを作成し、ためにサーバを引っ張るエンジンを呼び出しを開始するために、そのタイマータスクを登録します。
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;
};
}
エンジンは、GUIスレッドでAsyncTaskサブクラスインスタンスを作成して実行するだけです。 onPostExecuteは、Activityで割り当てられたUIコンポーネントを呼び出すコンソールに行を書き込みます。
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インスタンスの作成から始め、私はそれはそれ自体でUIスレッド上で実行するが、私は最終的に役に立たない、まだ、このアプローチに来て問題を解決しようとするだろうという印象の下にありました。ちょうど私がここでたくさん試したと言いたい。
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);
}
}
だから、問題は、それが一度だけ正常に実行されることで、タイマーのスケジュール、エンジンの最初の時間を呼び出し、それを取得、それはサーバーを引っ張る、RequestTaskを実行します応答し、コンソールに表示します。しかし、それはタイマーの方法に入ってから、サービスから生命の兆候が現れません。 LogCatで例外は発生せず、RequestTaskのログは出力されません。
もちろん、デバッグには時間がかかるでしょうが、おそらく誰かがこの苦痛から私を救い、コードにエラーを表示できますか? Executor自体は、Engine.tick()呼び出しをコメントするために完全に連続して動作します。
解決の手がかりとして非常に役立ちます。それは、スレッドに関連する規則を次のようになりますAsyncTaskのドキュメントで
Engine.tick() - new RequestTask()。execute(requestURL);これは実際に私が行うことです。 – kirhgoff
新しいRequestTask()を実行しようとしましたか?execute(requestURL); requestURLはおそらくrequestURL1,2などに変更されます。 –
これはどうやって助けてくれるのか分かりません。 @CommonsWareによる返事をチェックしてください。彼のアプローチはもっとAndroidに似ています。 – kirhgoff