为什么我的服务每秒发送20个请求而不是每10秒发送1个请求

时间:2017-02-26 17:04:18

标签: java android http

我正在尝试提供每10秒发送一次请求的服务。 主要任务是每10秒发出一次请求,并在recycleview中更新对象列表。

import android.app.Service;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;

public class HttpSenderService extends Service {
private String SERVER_IP;
private int PORT;
HttpSenderServiceBinder binder = new HttpSenderServiceBinder();

Runnable mHandlerTask = new Runnable()
{
    @Override
    public void run() {
        new makeRequest().execute();
        mHandler.postDelayed(mHandlerTask, 3000);
    }
};

public HttpSenderService() {
}

private static String TAG = HttpSenderService.class.getSimpleName();
private String msgGetWarningAlarm = "<?xml version=\"1.0\"?><request><track_get_warning_alarm version=\"" + MainActivity.reqV + "\"/></request>";
public boolean isRunning = false;
private String response_str;
Handler mHandler;

String getResponse_str(){
    return response_str;
}


@Override
public IBinder onBind(Intent arg0) {
    return binder;
}

@Override
public void onCreate() {
    super.onCreate();
    Log.d(TAG, "onCreate");
    mHandler = new Handler();
    SharedPreferences mySettings = getSharedPreferences("MainActivity", MODE_PRIVATE);
    if (!mySettings.getString("SERVER_IP", "").equals("")) {
        SERVER_IP = mySettings.getString("SERVER_IP", "");
    }
    PORT = mySettings.getInt("PORT", 0);
}

@Override
public synchronized void onDestroy() {
    super.onDestroy();
    Log.d(TAG, "onDestroy");
    stopRepeatingTask();
}

@Override
public synchronized void onStart(Intent intent, int startId) {
    super.onStart(intent, startId);
    Log.d(TAG, "onStart");
    startRepeatingTask();
}

//...........
private class makeRequest extends AsyncTask<Void, Void, Void> {
    @Override
    protected Void doInBackground(Void... v) {
        try {
            if (SERVER_IP != null && !SERVER_IP.equals("") && PORT > 0) {
                HttpClient httpclient = new DefaultHttpClient();
                HttpPost httppost = new HttpPost("http://" + SERVER_IP + ":" + Integer.toString(PORT) + "/");
                // Add your data
                StringEntity se = null;
                try {
                    se = new StringEntity(msgGetWarningAlarm);
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
                se.setContentType("text/xml");
                httppost.setEntity(se);
                ResponseHandler<String> responseHandler = new BasicResponseHandler();
                response_str = null;
                try {
                    response_str = httpclient.execute(httppost, responseHandler);
                    if (!response_str.equalsIgnoreCase("")) {
                        return null;
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return null;
    }

    @Override
    protected void onPostExecute(Void v) {
        fireReturnListeners(HttpSenderService.this);
        new Handler().postDelayed(new Runnable() {
            public void run() {
                new makeRequest().execute();
            }
        }, 10000);
    }
}

public interface HttpReceivedListener {
    void onHttpReceived(HttpSenderService service);
    // or void onEvent(); as per your need
}

private ArrayList<HttpSenderService.HttpReceivedListener> listeners = new ArrayList<HttpSenderService.HttpReceivedListener>();

public void addHttpReceivedListener(HttpSenderService.HttpReceivedListener listener) {
    listeners.add(listener);
}

public void removeReturnListener(HttpSenderService.HttpReceivedListener listener) {
    listeners.remove(listener);
}

private void fireReturnListeners(HttpSenderService service) {
    for (HttpSenderService.HttpReceivedListener listener : listeners) {
        listener.onHttpReceived(service);
    }
}

class HttpSenderServiceBinder extends Binder {
    HttpSenderService getService() {
        return HttpSenderService.this;
    }
}

void startRepeatingTask()
{
    mHandlerTask.run();
}

void stopRepeatingTask()
{
    mHandler.removeCallbacks(mHandlerTask);
}
}

请告诉我们如何正确服务这样的服务。该应用程序的先前版本没有服务,请求是通过警报管理器实现的,下一个版本是使用Thread的服务,现在我尝试使用异步任务,但是当我启动服务时它会匹配请求。也许有一些图书馆。

2 个答案:

答案 0 :(得分:1)

您正在从(至少)两个地方向处理程序发送消息AsyncTaks.postExecute和mHandlerTask其自身。因此,当它第一次被放置时,它会触发其自身的下两次执行,然后是4,8,16 ......只要硬件能够处理这些需求的时间和速度都很快。

Runnable mHandlerTask = new Runnable()
{
    @Override
    public void run() {
        new makeRequest().execute();
        mHandler.postDelayed(mHandlerTask, 3000); //remove this line!
    }
};

/或此块

new Handler().postDelayed(new Runnable() {
    public void run() {
        new makeRequest().execute();
    }
}, 10000);

答案 1 :(得分:0)

移动时间码:

@Override
protected void onPostExecute(Void v) {
    fireReturnListeners(HttpSenderService.this);
    new Handler().postDelayed(new Runnable() {
        public void run() {
            new makeRequest().execute();
        }
    }, 10000);
}

改变这个:

void startRepeatingTask()
{
    mHandlerTask.run();
}

到此:

void startRepeatingTask()
{
    new Handler().postDelayed(new Runnable() {
        public void run() {
            new makeRequest().execute();
        }
    }, 10000);

}

每次代码运行时,您都在创建一个新的Handler.postDelayed,这就是您最终发送20个请求的原因。删除onPostExecute中的重复。

你所做的“错误”是递归调用。这些会重新创建自己,并且由于放置,每次调用代码时都会创建更多处理程序。