Android:使用 AsyncTask 进行重复 Ajax 调用的含义 [英] Android: Implication of using AsyncTask to make repeated Ajax Calls

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

问题描述

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

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. 进行 AJAX 调用,并在收到响应后更新 UI - 为此,我使用了一个简单的 AsyncTask.
  2. 定期重复上述操作.

我还没有想出一种优雅的方法来实现上面的第 2 点.目前,我只是从 OnPostExecute() 执行任务本身.我在 SO 上的这个线程 上读到,我不需要担心垃圾收集与 AsyncTask 对象有关.

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.

但我仍然不确定如何设置一个计时器,以便在它到期后触发我的 AsyncTask.任何指针将不胜感激.这是我的代码:

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);
        }

    }

}

提前致谢

我尝试发布答案但无法发布,因为我没有在 8 小时内回复的声誉.

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. 我在使用它时有什么需要注意的方面吗?特别是,我看到 LogCat 中发生了很多 GC.另外,我想知道 AsyncTask 如何成为 GC 的候选对象,除非 onPostExecute() 完成?

  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?

如何停止"更新?我想到的一种方法是将第一个 AsyncTask 实例作为 Activity 的成员变量.这样,我可以在它上面调用 cancel(true) 并希望这会停止"任务.

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.

<小时>

解决方案:

如果有人正在寻找类似的东西 - 我在这里提到的所有解决方案都不能令人满意.它们都遇到 OutOfMemory 问题.我没有调试 OOM 的细节,但我怀疑这可能是因为递归,或者因为将 HTTP 相关的对象作为 AsyncTask 中的成员变量而不是作为成员变量Activity(主要是因为没有重用 HTTP 和其他对象).


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).

我为另一种方法放弃了这种方法 - 在我的 AsyncTaskdoInBackground() 中无休止地进行 Ajax 调用;并在 onProgressUpdate() 中更新 UI.这样我也避免了维护太多线程或 Handler 来更新 UI 的开销(记住 UI 可以在 onProgressUpdate() 中更新).

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() ).

这种方法还消除了对 Timers 和 TimerTasks 的需要,有利于使用 Thread.sleep() 代替.SO 上的这个线程 有更多细节和代码片段也是.

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.

推荐答案

在任何 View 上调用 postDelayed() 来安排一大块代码在主视图上运行一定延迟后的应用程序线程.在 AsyncTaskonPostExecute() 中执行此操作以创建并执行另一个 AsyncTask.

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.

您可以使用 AlarmManager,正如其他人所引用的那样,但我同意您的看法,对于纯粹在活动中发生的计时来说,这感觉有点矫枉过正.

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.

话虽如此,如果无论活动是否存在都应该发生 AJAX 调用,请务必考虑切换到 AlarmManagerIntentService.

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

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

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