【问题标题】:service to run http command causing infinite loop服务运行 http 命令导致无限循环
【发布时间】:2014-07-15 12:38:56
【问题描述】:

基本上,我希望服务在后台运行并生成 http 请求(因此是异步任务)。我希望服务在连接出现错误时停止。这只会在 LAN 上运行,并在 main 提示使用新的 ip 地址时停止并重新启动,并在用户退出应用程序时停止。

我可以让服务启动和停止并更新 ip 就好了。当 IP 地址无法访问时,麻烦就来了。我得到错误,我抓住它们。我破坏了服务,它继续运行......就像一个僵尸......拥有坚不可摧的四肢和对愚蠢的渴望

这里是服务:

public class fanInfoService extends Service {

public String _ip = null;
public String _stopService = null;
public Long _startTime = (long) 0;

public fanInfoService() {
    super();
}

@Override
public int onStartCommand(Intent intent, int flags, int startId)
{ 
// get information from intent
  Bundle b = intent.getExtras();
  _ip = b.getString("ip");
  _stopService = b.getString("STOP");
  _startTime = b.getLong("startTime");


  if(_stopService != null){
      alarmCancel();
      onDestroy();
      System.out.println("stopping due to stopService");

  }else{
      //else set stopService to null and run as usual
      //_stopService = null;
      System.out.println("onhandle called again with " + _ip);
      try{
          new RequestTask().execute("http://"+ _ip +"/fanspd.cgi");
      }catch(RuntimeException e){
          System.out.println("we caught an error");
      }
     // RequestTask("http://"+ _ip +"/fanspd.cgi");
  }

  return START_NOT_STICKY;
}

@Override
public void onDestroy(){
  //if we want to stop service come here

  super.onDestroy();
  //super.stopSelf();
  System.out.println("Here we are stopping things on Destroy");

} 

@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}

private void scheduleNextUpdate()
{
Intent intent = new Intent(this, this.getClass());
Bundle b = new Bundle();
b.putString("ip", _ip);
b.putLong("startTime", _startTime);
intent.putExtras(b);

PendingIntent pendingIntent =
    PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);


// The update frequency should often be user configurable.  This is not.

long currentTimeMillis = System.currentTimeMillis();
long nextUpdateTimeMillis = currentTimeMillis + 2500;
Time nextUpdateTime = new Time();
nextUpdateTime.set(nextUpdateTimeMillis);

AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);

//Also stop if the signal comes to stop

if(_stopService != null){
    if(_stopService.equals("stop")){
        System.out.println("here I am Stopping the Refresh Thread " + _stopService);
        alarmCancel();
        onDestroy();
    }else{
        System.out.println("Somthings wrong in fanService _stopService");
    }
}else{
    //alarmManager.set(AlarmManager.RTC, nextUpdateTimeMillis, pendingIntent);
    System.out.println("Here we set the repeat call");
    alarmManager.setInexactRepeating(AlarmManager.RTC, nextUpdateTimeMillis, 30, pendingIntent);
}
}

//Here is the async class to send http request
public class RequestTask extends AsyncTask<String, String, 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{
                //Closes the connection.
                response.getEntity().getContent().close();
                throw new IOException(statusLine.getReasonPhrase());
            }
        } catch (ClientProtocolException e) {
            System.out.println("Client Side Error");
            e.printStackTrace();
            runErrorCode();
            return null;
        } catch (IOException e) {
            System.out.println("I-O side Error");
            e.printStackTrace();
            runErrorCode();
            onDestroy();
            return null;
        }
        return responseString;
    }

    @Override
    protected void onPostExecute(String result) {
        super.onPostExecute(result);
        //Do anything with response..

        //Take response and send back to Main for parseHTTP via intent
        Intent intent = new Intent("com.example.airscapefancontroller.android.action.broadcast");
        //System.out.println("Here is results " + result);
        Bundle extras = new Bundle();  
        extras.putString("RESULT", result);
        extras.putString("REFRESH", null);
        intent.putExtras(extras);

        sendBroadcast(intent);
        scheduleNextUpdate();
        onDestroy();
        System.out.println("I just posted results");

    }
}

  private void runErrorCode(){
      Intent intent = new Intent("com.example.airscapefancontroller.android.action.broadcast");
        //send a signal back to reset the stats
        Bundle extras = new Bundle();  
      extras.putString("RESULT", "refresh");
      intent.putExtras(extras);

      System.out.println("Here we are in error code ");
     // alarmCancel();
      sendBroadcast(intent);
      stopSelf();
      onDestroy();

  }


    private void alarmCancel(){
        Intent intent = new Intent(this, this.getClass());
        Bundle b = new Bundle();
        b.putString("ip", _ip);
        b.putLong("startTime", _startTime);
        intent.putExtras(b);

        PendingIntent pendingIntent =
            PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
        AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);

        alarmManager.cancel(pendingIntent);
        pendingIntent.cancel();
        onDestroy();
        System.out.println("We canceled the service and alarm");
    }

这是设备离开网络的 LogCat:

07-09 18:27:56.195: I/System.out(13375): we caught an error
07-09 18:27:56.250: I/System.out(13375): onhandle called again with 10.0.0.29
07-09 18:27:56.250: I/System.out(13375): we caught an error
07-09 18:27:56.257: I/System.out(13375): onhandle called again with 10.0.0.29
07-09 18:27:56.261: I/System.out(13375): we caught an error
07-09 18:27:56.281: I/System.out(13375): onhandle called again with 10.0.0.29
07-09 18:27:56.281: I/System.out(13375): we caught an error
07-09 18:27:56.312: I/System.out(13375): onhandle called again with 10.0.0.29
07-09 18:27:56.312: I/System.out(13375): we caught an error
07-09 18:27:56.343: I/System.out(13375): onhandle called again with 10.0.0.29
07-09 18:27:56.343: I/System.out(13375): we caught an error
07-09 18:27:56.378: I/System.out(13375): onhandle called again with 10.0.0.29
07-09 18:27:56.378: I/System.out(13375): we caught an error
07-09 18:27:56.402: I/System.out(13375): onhandle called again with 10.0.0.29
07-09 18:27:56.402: I/System.out(13375): we caught an error
07-09 18:27:56.414: I/System.out(13375): I-O side Error
07-09 18:27:56.414: W/System.err(13375): org.apache.http.conn.ConnectTimeoutException:     Connect to /10.0.0.29:80 timed out
07-09 18:27:56.414: W/System.err(13375):    at     org.apache.http.conn.scheme.PlainSocketFactory.connectSocket(PlainSocketFactory.java:121)
07-09 18:27:56.414: W/System.err(13375):    at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:159)
07-0 9 18:27:56.414: W/System.err(13375):   at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
07-09 18:27:56.414: W/System.err(13375):    at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
07-09 18:27:56.414: W/System.err(13375):    at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:359)
07-09 18:27:56.417: I/System.out(13375): I-O side Error
07-09 18:27:56.417: W/System.err(13375):    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
07-09 18:27:56.417: W/System.err(13375):    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
07-09 18:27:56.417: W/System.err(13375):    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)
07-09 18:27:56.417: W/System.err(13375):    at com.example.airscapefancontroller.fanInfoService$RequestTask.doInBackground(fanInfoService.java:137)
07-09 18:27:56.417: W/System.err(13375):    at com.example.airscapefancontroller.fanInfoService$RequestTask.doInBackground(fanInfoService.java:1)
07-09 18:27:56.417: W/System.err(13375):    at android.os.AsyncTask$2.call(AsyncTask.java:185)
07-09 18:27:56.417: W/System.err(13375):    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306)
07-09 18:27:56.417: W/System.err(13375):    at java.util.concurrent.FutureTask.run(FutureTask.java:138)
07-09 18:27:56.417: W/System.err(13375):    at   java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)
07-09 18:27:56.417: W/System.err(13375):    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)
07-09 18:27:56.421: W/System.err(13375):    at java.lang.Thread.run(Thread.java:1019)
07-09 18:27:56.421: I/System.out(13375): Here we are in error code 
07-09 18:27:56.437: W/System.err(13375): org.apache.http.conn.ConnectTimeoutException: Connect to /10.0.0.29:80 timed out
07-09 18:27:56.441: I/System.out(13375): onhandle called again with 10.0.0.29
07-09 18:27:56.441: I/System.out(13375): we caught an error
07-09 18:27:56.449: W/System.err(13375):    at org.apache.http.conn.scheme.PlainSocketFactory.connectSocket(PlainSocketFactory.java:121)
07-09 18:27:56.457: I/System.out(13375): I-O side Error
07-09 18:27:56.460: W/System.err(13375): org.apache.http.conn.ConnectTimeoutException: Connect to /10.0.0.29:80 timed out
07-09 18:27:56.460: I/System.out(13375): onhandle called again with 10.0.0.29
07-09 18:27:56.460: I/System.out(13375): we caught an error
07-09 18:27:56.464: I/System.out(13375): Here we are stopping things on Destroy
07-09 18:27:56.468: I/System.out(13375): Here we are stopping things on Destroy
07-09 18:27:56.468: I/System.out(13375): Here we are stopping things on Destroy
07-09 18:27:56.472: I/System.out(13375): Here we set the repeat call
07-09 18:27:56.472: I/System.out(13375): Here we are stopping things on Destroy
07-09 18:27:56.472: I/System.out(13375): I just posted results
07-09 18:27:56.472: W/System.err(13375):    at org.apache.http.conn.scheme.PlainSocketFactory.connectSocket(PlainSocketFactory.java:121)
07-09 18:27:56.472: W/System.err(13375):    at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:159)
07-09 18:27:56.476: W/System.err(13375):    at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
07-09 18:27:56.480: I/System.out(13375): I-O side Error
07-09 18:27:56.480: W/System.err(13375):    at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
07-09 18:27:56.484: W/System.err(13375): org.apache.http.conn.ConnectTimeoutException: Connect to /10.0.0.29:80 timed out
07-09 18:27:56.484: W/System.err(13375):    at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:159)
07-09 18:27:56.484: W/System.err(13375):    at org.apache.http.conn.scheme.PlainSocketFactory.connectSocket(PlainSocketFactory.java:121)
07-09 18:27:56.484: W/System.err(13375):    at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:159)
07-09 18:27:56.488: W/System.err(13375):    at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
07-09 18:27:56.488: W/System.err(13375):    at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
07-09 18:27:56.488: W/System.err(13375):    at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:359)
07-09 18:27:56.488: W/System.err(13375):    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
07-09 18:27:56.488: W/System.err(13375):    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
07-09 18:27:56.488: W/System.err(13375):    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)
07-09 18:27:56.488: W/System.err(13375):    at com.example.airscapefancontroller.fanInfoService$RequestTask.doInBackground(fanInfoService.java:137)
07-09 18:27:56.488: W/System.err(13375):    at com.example.airscapefancontroller.fanInfoService$RequestTask.doInBackground(fanInfoService.java:1)
07-09 18:27:56.492: W/System.err(13375):    at android.os.AsyncTask$2.call(AsyncTask.java:185)
07-09 18:27:56.496: W/System.err(13375):    at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:359)
07-09 18:27:56.496: W/System.err(13375):    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
07-09 18:27:56.496: W/System.err(13375):    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
07-09 18:27:56.496: W/System.err(13375):    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)
07-09 18:27:56.496: W/System.err(13375):    at com.example.airscapefancontroller.fanInfoService$RequestTask.doInBackground(fanInfoService.java:137)
07-09 18:27:56.500: W/System.err(13375):    at com.example.airscapefancontroller.fanInfoService$RequestTask.doInBackground(fanInfoService.java:1)
07-09 18:27:56.500: W/System.err(13375):    at android.os.AsyncTask$2.call(AsyncTask.java:185)
07-09 18:27:56.503: W/System.err(13375):    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306)
07-09 18:27:56.507: W/System.err(13375):    at java.util.concurrent.FutureTask.run(FutureTask.java:138)
07-09 18:27:56.511: I/System.out(13375): I-O side Error
07-09 18:27:56.519: W/System.err(13375):    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)
07-09 18:27:56.523: W/System.err(13375):    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)
07-09 18:27:56.523: W/System.err(13375):    at java.lang.Thread.run(Thread.java:1019)
07-09 18:27:56.523: I/System.out(13375): Here we are in error code 
07-09 18:27:56.523: W/System.err(13375):    at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
07-09 18:27:56.527: W/System.err(13375):    at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
07-09 18:27:56.527: W/System.err(13375):    at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:359)
07-09 18:27:56.527: W/System.err(13375):    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
07-09 18:27:56.527: W/System.err(13375):    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
07-09 18:27:56.527: W/System.err(13375):    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)
07-09 18:27:56.527: W/System.err(13375):    at com.example.airscapefancontroller.fanInfoService$RequestTask.doInBackground(fanInfoService.java:137)
07-09 18:27:56.527: W/System.err(13375):    at com.example.airscapefancontroller.fanInfoService$RequestTask.doInBackground(fanInfoService.java:1)
07-09 18:27:56.531: W/System.err(13375):    at android.os.AsyncTask$2.call(AsyncTask.java:185)
07-09 18:27:56.531: W/System.err(13375):    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306)
07-09 18:27:56.550: W/System.err(13375):    at java.util.concurrent.FutureTask.run(FutureTask.java:138)

感谢凯飞的帮助。我同意你打破我的编码员对这个问题的阻碍。

如果有人遇到类似问题,这篇文章对我很有帮助。

lq=1Helpful entry

我基本上将整个服务改回 IntentService 并实例化一个全局 public static volatile boolean 并将其设置为 shouldContinue = true;

此布尔值指示召回发生的方式和时间。效果很好

【问题讨论】:

  • 欢迎来到 Stack Overflow!您能否将您的程序简化为仍然显示问题的更简单的程序?
  • 当然。 onStartCommand 基本上检查我是否使用指示停止的字符串启动服务。如果没有,则运行 new RequestTask().execute("http://"+ _ip +"/fanspd.cgi"); (我将它放在 try catch 分支中以捕获拔出设备时出现的错误)异步执行后,我通过广播接收器和 onPostEcecute 将结果发布回 UI 线程。如果我在 new RequestTask().execute("http://"+ _ip +"/fanspd.cgi"); 中使用的 IP,这一切都很好。是活的。如果那消失了系统totalll

标签: android service


【解决方案1】:

服务应通过调用stopSelf() 方法自行终止。 onDestroy() 由 Android 操作系统调用。

参考:http://www.vogella.com/tutorials/AndroidServices/article.html#service_stop

【讨论】:

  • 有人会想,但不幸的是它只会喂野兽。 :) 我确实在多个地方调用了 onDestroy,但仍然没有。这对我来说是一个真正的障碍。据我所知,服务已停止,但系统循环仍在继续。
  • 您是绑定到服务(通过调用bindService())还是启动服务(通过调用startService())?
  • 我希望我有。我从不明确调用 bindService()。 :(
  • 哦,显然你调用了 startService()。那么为什么你不使用 stopSelf() 来停止服务,正如官方文档所说:developer.android.com/guide/components/services.html#Stopping
  • 另一个奇怪的事情是,当我关闭我的应用程序并向服务发送停止信号时,我可以让服务停止。无需调用 unBind()
【解决方案2】:

如果有人遇到类似问题,这篇文章对我很有帮助。

Helpful entry

我基本上将整个服务改回 IntentService 并实例化一个全局 public static volatile boolean 并将其设置为 shouldContinue = true;

此布尔值指示召回发生的方式和时间。效果很好

【讨论】:

    猜你喜欢
    • 2014-04-10
    • 2017-10-17
    • 2018-05-06
    • 2014-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多