【发布时间】:2013-12-06 14:20:16
【问题描述】:
出于测试目的,我制作了一个由简单活动组成的小型 android 应用程序,您可以在其中插入主机、端口和间隔(以秒为单位)。该应用程序启动一个服务,该服务创建一个线程,该线程的循环从套接字的输入流中读取,直到它被有意停止。 这是服务的代码:
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
prepareFileLogging();
FILELOG.info("PollingService: onStartCommand");
mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
Intent bIntent = new Intent(this, MainActivity.class);
PendingIntent pbIntent = PendingIntent
.getActivity(this, 0, bIntent, Intent.FLAG_ACTIVITY_CLEAR_TOP);
Notification.Builder bBuilder =
new Notification.Builder(this)
.setSmallIcon(android.R.drawable.stat_notify_sync)
.setContentTitle("PollingTest")
.setContentText("Servizio di polling attivo")
.setAutoCancel(true)
.setOngoing(true)
.setContentIntent(pbIntent);
this.startForeground(1, bBuilder.build());
Log.i("PollingService", "Received start id " + startId + ": " + intent);
FILELOG.info("PollingService: Received start id " + startId + ": " + intent);
hostName = intent.getExtras().getString(PAR_HOST);
portNumber = intent.getExtras().getInt(PAR_PORT);
freqSeconds = intent.getExtras().getInt(PAR_FREQ);
if(pollingThread == null){
FILELOG.info("pollingThread not running: starting...");
pollingThread = new Poll();
pollingThread.start();
}
Toast.makeText(this, "Servizio in Background: ServizioSincronizzazione.onCreate()",
Toast.LENGTH_LONG).show();
mReceiver = new BroadcastRec();
getApplication().registerReceiver(mReceiver, filter);
return START_REDELIVER_INTENT;
}
@Override
public void onDestroy() {
mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
Notification.Builder bBuilder = new Notification.Builder(this)
.setSmallIcon(android.R.drawable.stat_notify_error).setContentTitle(
"PollingTest")
.setContentText("Il Servizio di polling è sinterrotto");
Toast.makeText(this, "Servizio interrotto", Toast.LENGTH_SHORT).show();
getApplication().unregisterReceiver(mReceiver);
stopPollingService();
Log.i("PollingService", "onDestroy");
super.onDestroy();
}
private class Poll extends Thread {
@Override
public void run() {
Thread thisThread = Thread.currentThread();
FILELOG.info("pollingThread: started");
try {
Socket echoSocket = new Socket(hostName, portNumber);
PrintWriter out =
new PrintWriter(echoSocket.getOutputStream(), true);
BufferedReader in =
new BufferedReader(
new InputStreamReader(echoSocket.getInputStream()));
int nanos = 250000;
while (pollingThread == thisThread) {
Log.i("PollThread", "start of a new call");
out.println("prova");
String response = in.readLine();
FILELOG.info("pollingThread: server response: " +response);
System.out.println("server: " + response);
if (response != null && response.equals("null")) {
FILELOG.info("pollingThread: server down (reponse 'null'), new socket");
echoSocket = new Socket(hostName, portNumber);
}
sendBroadcast(new Intent());
try {
Log.i("PollThread", "timeout start...");
Thread.sleep(freqSeconds*1000, nanos);
} catch (InterruptedException e) {
Log.i("PollThread", e.getMessage());
FILELOG.info("pollingThread error: " + e.getMessage());
}
}
} catch (UnknownHostException e) {
FILELOG.info("pollingThread error: Don't know about host " + e.getMessage());
System.err.println("Don't know about host " + hostName);
stopPollingService();
} catch (IOException e) {
FILELOG.info("pollingThread error: Couldn't get I/O for the connection to " + e.getMessage());
System.err.println("Couldn't get I/O for the connection to " +
hostName);
stopPollingService();
}
}
}
我让应用程序在平板电脑上运行了一天,分析了电池的消耗情况以及两次向服务器发出请求的时间间隔。 我注意到的问题是,大约 10 分钟,5 秒的间隔得到遵守,然后它在 5 到 20 秒之间变化! 平板电脑已被唤醒几次并解锁,服务从未崩溃。 这是服务器观察到的间隔序列:
有人能想到为什么会这样吗?
【问题讨论】:
-
我认为您的服务正在被系统破坏,然后以不规则的时间间隔重新启动,因为您正在从 onStartCommand 发送重新交付意图常量。你说服务器没有崩溃,但是 onDestroy 曾经被调用过吗?
-
onDestroy 永远不会被调用,而 onStartCommand 只会被调用一次!