【发布时间】:2012-01-17 21:15:14
【问题描述】:
我正在尝试创建一个简单的 Android 程序,该程序每 30*1000 毫秒拉一次 Web 服务器。我的应用程序中有专门的服务 - 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;
};
}
引擎只是在 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);
}
}
Yak,我从简单的 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 没有打印出来。
当然是时候开始调试了,但也许有人可以让我摆脱这种痛苦并在代码中显示错误?如果对 Engine.tick() 调用进行注释,则执行程序本身可以完美地连续工作。
对于解决问题的线索非常有用。
【问题讨论】:
标签: java android multithreading httpclient android-asynctask