安卓:启示使用的AsyncTask使重复Ajax调用的 [英] Android: Implication of using AsyncTask to make repeated Ajax Calls

查看:130
本文介绍了安卓:启示使用的AsyncTask使重复Ajax调用的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要我的Andr​​oid应用程序从服务器使用AJAX调用定期获取数据,并相应地更新UI(只是一堆的TextView S的需要与更新的setText())。请注意,这涉及到两个任务:

  1. 在制作AJAX调用,并更新用户界面,一旦我得到的回应 - 我用一个简单的的AsyncTask
  2. 在做上述重复,每隔一段时间。

我还没有想出一种优雅的方式实现2点上方。目前,我只是从 OnPostExecute执行任务本身()。我读了这个线程SO ,我不必担心垃圾收集尽可能在AsyncTask的对象有关。

但我还是不能确定我如何设置一个计时器到期之后,将触发我的AsyncTask的。任何指针将AP preciated。这是我的code:

 公共类MyActivity延伸活动{


    / **第一次创建活动时调用。 * /
    @覆盖
    公共无效的onCreate(包savedInstanceState){
        super.onCreate(savedInstanceState);
        的setContentView(R.layout.main);

        新AjaxRequestTask()执行(MY_REST_API_URL);

    }

    私人无效updateReadings(字符串newReadings){
           //更新用户界面
        }

    类AjaxRequestTask扩展的AsyncTask<字符串,整数,字符串> {

        @覆盖
        保护字符串doInBackground(字符串... restApiUrl){
                    //做AJAX请求
                }

        @覆盖
        保护无效onPostExecute(字符串结果){
            updateReadings(结果);
                     / *是否有一个更优雅的方式来实现这一目标不是创建一个新的AsyncTask对象,每10秒?另外,我该如何更新UI,如果我在这里创建一个定时器? * /
            新AjaxRequestTask()执行(MY_REST_API_URL);
        }

    }
 

}

在此先感谢

编辑: 我试图张贴一个答案,但不能这样做,因为我没有足够的信誉在8小时内回答。

嘛,所以我找到了解决办法。我不相信但是。

 保护无效onPostExecute(字符串结果){

            updateReadings(结果);
            // super.onPostExecute(结果);
            新的Timer()。时间表(
                    新的TimerTask(){
                        @覆盖
                        公共无效的run(){
                            新AjaxRequestTask()执行(MY_REST_API_URL);
                        }
                    },
                    TIMER_ONE_TIME_EXECUTION_DELAY
            );
        }
 

  1. 有没有翻盖两侧,我应该知道,当我用这个的?特别是,我看到很多地方选区发生在LogCat中的。另外,我想知道如何在的AsyncTask 可以是候选人GC除非 onPostExecute()完成?

  2. 我怎样才能停止的更新?我想到了一个办法是让第一个的AsyncTask 实例作为活动的成员变量。这样一来,我可以调用取消(真)就可以了,希望这将停止的任务。


解决方案

在万一有人正在寻找类似的东西 - 没有我这里提到的解决方案,工作令人满意。他们都患有内存不足的问题。我并没有调试到OOM的细节,但我怀疑这既可以是递归的原因,还是因为有HTTP相关对象作为成员变量的AsyncTask 而不是作为活动的(基本上,因为不是重复使用HTTP和其他对象)的成员。

我放弃了这个,对于一个不同的 - 让我的阿贾克斯不断地调用在 doInBackground()我的的AsyncTask ;和更新用户界面在 onProgressUpdate()。这样,我也避免维护太多的线程或处理程序 S表示更新UI(记住UI可以在 onProgressUpdate更新())。

此方法还省去了定时器的TimerTask S,有利于使用视频下载()代替。 <一href="http://stackoverflow.com/questions/6652390/android-timertask-scheduled-for-repetition-getting-fired-only-once">This线程SO 有更多的细节和code段了。

解决方案

呼叫 postDelayed()任何查看以计划code一大块一定的延迟后运行的主应用程序线程上。在 onPostExecute做到这一点()的AsyncTask 来创建并执行其他的AsyncTask

您可以使用 AlarmManager ,正如其他人提到,但我同意你,这感觉有点像矫枉过正的时间发生完全的活动中。

这就是说,如果Ajax调用应该发生,无论活动是否存在,肯定会考虑改用 AlarmManager IntentService

I need my Android app to periodically fetch data from a server using AJAX calls, and update the UI accordingly (just a bunch of TextViews that need to be updated with setText()). Note that this involves 2 tasks:

  1. Making an AJAX call, and updating the UI once I receive a response - I use a simple AsyncTask for this.
  2. Doing the above repeatedly, at regular intervals.

I haven't figured out an elegant way to achieve Point 2 above. Currently, I am simply executing the task itself from OnPostExecute(). I read on this thread at SO that I need not worry about garbage collection as far as the AsyncTask objects are concerned.

But I'm still unsure as to how I set up a timer that will fire my AsyncTask after it expires. Any pointers will be appreciated. Here is my code:

public class MyActivity extends Activity {


    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        new AjaxRequestTask().execute(MY_REST_API_URL);

    }

    private void updateReadings(String newReadings) {
           //Update the UI
        }

    class AjaxRequestTask extends AsyncTask<String, Integer, String> {

        @Override
        protected String doInBackground(String... restApiUrl) {
                    //Do AJAX Request
                }

        @Override
        protected void onPostExecute(String result) {
            updateReadings(result);
                     /*Is there a more elegant way to achieve this than create a new AsyncTask object every 10 seconds?  Also, How can I update the UI if I create a timer here? */
            new AjaxRequestTask().execute(MY_REST_API_URL);
        }

    }

}

Thanks in advance

EDIT: I tried posting an answer but couldn't do it since I don't have the reputation to answer within 8 hours.

Well, so I found a solution. I'm not convinced however.

protected void onPostExecute(String result) {

            updateReadings(result);
            // super.onPostExecute(result);
            new Timer().schedule(
                    new TimerTask() {
                        @Override
                        public void run() {
                            new AjaxRequestTask().execute(MY_REST_API_URL);
                        }
                    }, 
                    TIMER_ONE_TIME_EXECUTION_DELAY
            );
        }

  1. Are there any flip sides that I should be aware of when I use this? In particular, I am seeing lots of GCs happening in the LogCat. Also, I am wondering how an AsyncTask can be candidate for GC unless the onPostExecute() completes?

  2. How can I "stop" the updates? One way I thought of was to make the very first AsyncTask instance as a member variable of the Activity. That way, I can invoke cancel(true) on it and hope that this will "stop" the tasks.


SOLUTION:

In case anyone is looking for something similar - none of the solutions I mentioned here work satisfactorily. They all suffer from OutOfMemory issues. I did not debug into the details of the OOM, but I suspect it could either be because of the recursion, or because of having HTTP-related objects as member variables in the AsyncTask rather than as members of the Activity (basically because of NOT reusing HTTP and other objects).

I discarded this approach for a different one - making my Ajax Calls endlessly in the doInBackground() of my AsyncTask; and updating the UI in onProgressUpdate(). That way I also avoid the overhead of maintaining too many threads or Handlers for updating the UI (remember UI can be updated in onProgressUpdate() ).

This approach also eliminates the need for Timers and TimerTasks, favoring the use of Thread.sleep() instead. This thread on SO has more details and a code snippet too.

解决方案

Call postDelayed() on any View to schedule a hunk of code to be run on the main application thread after a certain delay. Do this in onPostExecute() of the AsyncTask to create and execute another AsyncTask.

You could use AlarmManager, as others have cited, but I would agree with you that it feels a bit like overkill for timing that occurs purely within an activity.

That being said, if the AJAX calls should be occurring regardless of whether the activity exists, definitely consider switching to AlarmManager and an IntentService.

这篇关于安卓:启示使用的AsyncTask使重复Ajax调用的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆