为什么AlarmManager执行两次异步Http请求?

时间:2014-08-15 07:19:39

标签: android alarmmanager android-async-http

更新: 我发现了我的"两次"问题原因。我开始了#34; runAlarm()"两次。 所以下面的代码工作正常。 它定期发送Async HTTP请求。 您应该添加以显示此行:

<receiver  android:process=":remote" android:name="Alarm"></receiver>

原始问题: 我使用AlarmManager定期做HTTP请求。 它在循环中工作正常。 但每个HTTP请求都执行两次。 我已经使用了一些AlarmManager示例而没有理解是什么意思&#34; bla-bla&#34;那里。 如果你问我为什么不使用Timer, 我的答案是,我试图触摸计时器线程中的视图以显示HTTP请求的结果时出错。 我的代码如下。 提前谢谢!。

    private void startHttpRequests() {
         setAlarm();
    }

public void setAlarm()
{
    BroadcastReceiver receiver = new BroadcastReceiver() {
        @Override public void onReceive( Context context, Intent _ )
        {
            asyncPostRequest();
            context.unregisterReceiver( this ); // this == BroadcastReceiver, not Activity
        }
    };
    this.registerReceiver( receiver, new IntentFilter("com.blah.blah.somemessage") );
    PendingIntent pintent = PendingIntent.getBroadcast( this, 0, new Intent("com.blah.blah.somemessage"), 0 );
    AlarmManager manager = (AlarmManager)(this.getSystemService( Context.ALARM_SERVICE ));
    pollPeriod=1000*10;
    manager.set( AlarmManager.ELAPSED_REALTIME_WAKEUP,
            SystemClock.elapsedRealtime() + pollPeriod, pintent );
}
private void asyncPostRequest() {
    new HttpPostDemo().execute("http://www.google.com");
}

@Override
protected void onPostExecute(String result)  //HTTP POST result
{
    printDebug("received="+result);
    setAlarm();
}

public class HttpPostDemo extends AsyncTask<String, Void, String>
{
    @Override
    protected String doInBackground(String... urls)
    {
        BufferedReader inBuffer = null;
        String url= urls[0];
        String result = "fail";
        try {
            HttpClient httpClient = new DefaultHttpClient();
            HttpPost request = new HttpPost(url);
            List<NameValuePair> postParameters =
                    new ArrayList<NameValuePair>();
            postParameters.add(new BasicNameValuePair("operanda", "5"));
            postParameters.add(new BasicNameValuePair("operandb", "6"));
            postParameters.add(new BasicNameValuePair("answer", "11"));
            UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(
                    postParameters);

            request.setEntity(formEntity);
            HttpResponse httpResponse = httpClient.execute(request);
            inBuffer = new BufferedReader(
                    new InputStreamReader(
                            httpResponse.getEntity().getContent()));

            StringBuffer stringBuffer = new StringBuffer("");
            String line = "";
            String newLine = System.getProperty("line.separator");
            while ((line = inBuffer.readLine()) != null) {
                stringBuffer.append(line + newLine);
            }
            inBuffer.close();

            result = stringBuffer.toString();

        } catch(Exception e) {
            // Do something about exceptions
            result = e.getMessage();
        } finally {
            if (inBuffer != null) {
                try {
                    inBuffer.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return result;
    }

1 个答案:

答案 0 :(得分:1)

public class HttpRequestAlarm extends BroadcastReceiver {

    private static final int REQUEST_CODE = 0;

    private static final String TAG_CLASS_NAME = HttpRequestAlarm.class
            .getName();

    private Context context;

    private int timeInterval;

    public HttpRequestAlarm() {
    }

    public HttpRequestAlarm(Context context, int timeInterval) {
        this.context = context;
        this.timeInterval = timeInterval;
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        asyncPostRequest();
    }

    public void start() {
        Intent intentAlarm = new Intent(context, HttpRequestAlarm.class);
        PendingIntent pendingIntent = PendingIntent.getBroadcast(context,
                REQUEST_CODE, intentAlarm, PendingIntent.FLAG_UPDATE_CURRENT);
        AlarmManager alarmManager = (AlarmManager) context
                .getSystemService(Context.ALARM_SERVICE);
        alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP,
                System.currentTimeMillis(), timeInterval * 1000, pendingIntent);
        Log.i(TAG_CLASS_NAME, "Alarm scheduled for every " + timeInterval
                + " seconds");
    }

    public void stop() {
        Intent intentAlarm = new Intent(context, HttpRequestAlarm.class);
        PendingIntent pendingIntent = PendingIntent.getBroadcast(context,
                REQUEST_CODE, intentAlarm, 0);
        AlarmManager alarmManager = (AlarmManager) context
                .getSystemService(Context.ALARM_SERVICE);
        alarmManager.cancel(pendingIntent);
        Log.i(TAG_CLASS_NAME, "Alarm stopped");
    }
}

在项目的Manifest.xml中只注册一次接收者

    <receiver android:name="<your.package.name.>HttpRequestAlarm" />

最后创建一个HttpRequestAlarm对象并调用start方法。这将安排您的闹钟在每次提供的timeInterval之后重复触发。

注意:如果您想要执行您的http呼叫,即使您的设备处于初始状态,那么您必须在http呼叫之前获取唤醒锁,并在呼叫完成后释放它。