在无限循环中调用AsyncTask从服务器提取数据是一种好方法吗?

时间:2014-04-09 06:52:11

标签: android android-asynctask android-handler

在应用程序中我尝试每隔4秒从服务器中提取数据,然后更新应用程序。 我使用处理程序,因为我每隔4秒就调用一次AsynTask从服务器获取数据。

我是否担心每4秒钟为AsynTask创建的实例会导致任何问题?

这就是我正在做的事。

private static final int DELAY = 1000 * 4; final Handler printHandler = new Handler(); private boolean keepLooping = true; printHandler.postDelayed(printStuff, DELAY);

Runnable printStuff = new Runnable(){ @Override public void run(){ // call AsynTask to perform network operation on separate thread new DownloadMainScore().execute("http://server/root/score.php"); if(keepLooping) printHandler.postDelayed(this, DELAY); } };

4 个答案:

答案 0 :(得分:3)

选择并发工具

你说得对,这是不对的。在设计需要更新UI的偶然异步调用时,AsyncTasks被设计为有用的帮助程序。因此,在旧的(< 1.6)版本的Android中,最大线程池大小为10!

最好直接使用非常强大的Java,其中构建了AsyncTask。如果您想反复执行此操作,请尝试ScheduledExecutorService。我看到他们甚至为你做了一个很好的例子。

或者,鉴于您似乎得分较低,最好的方法是保持与XMPP之类的协议的持久连接,其中有许多Java服务器和客户端。

最后,您可能希望看一下gcm

关于一般的设计问题

我发现你想经常打印一个分数。实际上每四秒一次。但重点是分数没有变化?此外,如果您的互联网连接速度较慢,8秒钟之后,4秒前的连接速度尚未完成,该怎么办?现在你将启动另一个下载请求,即使它回来时另一个请求是最新的!

解决方案是解耦下载机制和UI更新机制。一种方法是在单个线程执行器上安排您的预定下载 - 而不是您可以在AsyncTask中控制的内容,在完成时会导致UI更新并显示分数。

祝你好运!

代码草图

现在还没有设置环境,但是在一个非常粗略的代码草图(检查语法)中,使用预定的执行程序将如下所示: 在课堂上:

private final ScheduledExecutorService downloadScheduler = Executors.newSingleThreadScheduledExecutor(1);

然后在别处,无论你在哪里开始这样做

final Runnable scoreHttpRunnable = new Runnable() {
    @Override public void run() {
...
//do Http Syncronously here- I guess whatever is in the doInBackground(...) part of that Async task you wrote!
...
final int newScoreResult = ... (do whatever you do here)
...
runOnUiThread(new Runnable() { @Override public void run() { yourView.updateHoweverYouLike(newScoreResult); } })
...
};
downloadScheduler.scheduleAtFixedRate(scoreHttpRunnable, 0, 4, TimeUnit.SECONDS);

在一个问题的单个答案中发布其他两条路线中的一条真的太多了。如果还没有问题,这将成为另一个问题。

答案 1 :(得分:2)

确保下一次调用只有在完成后才发送给asyc类,才能生成一个变量(IsLoadRunning),并在on preExecute()false onPOstExecute中将其设为true并添加条件if(!IsLoadRunning){new DownloadMainScore().execute();}

答案 2 :(得分:1)

作为official documentation

AsyncTasks should ideally be used for short operations (a few seconds at the most.)

服务可以更好地为您服务。看一下接受的答案here

答案 3 :(得分:-1)

@Override
protected String doInBackground(String... params) {
    Log.d(TAG, "type - " + params[0] + ", url = " + params[1] + ", name = " +   params[2]);


    downloadFile(params[1], params[2]);


    return null;
}

这是下载方法

URL url = new URI(Url.replace(" ", "%20")).toURL();
        URLConnection connection = url.openConnection();
        connection.setConnectTimeout(1000);
        int fileLength = connection.getContentLength();

        mSavePath = CommonUtilities.getFileSavePath(mContext, fileName, fileLength);
        Log.d(TAG, "*** saveFilePath - " + mSavePath);

        InputStream inputStream = connection.getInputStream();
        if (inputStream != null) {
            File file = new File(mSavePath);

            BufferedOutputStream bufferOutputStream = new   BufferedOutputStream(new FileOutputStream(file));
            byte byteArray[] = new byte[1024];
            int len = 0;
            long total = 0;

            while ((len = inputStream.read(byteArray)) != -1) {
                bufferOutputStream.write(byteArray, 0, len);
                total += len;
            }

            bufferOutputStream.flush();
            bufferOutputStream.close();
            inputStream.close();
        } else {
            Log.d(TAG, "*** inputStream is null");

        }