Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/208.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 在无限循环中调用AsyncTask从服务器提取数据是一种好方法吗?_Android_Android Asynctask_Android Handler - Fatal编程技术网

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

Android 在无限循环中调用AsyncTask从服务器提取数据是一种好方法吗?,android,android-asynctask,android-handler,Android,Android Asynctask,Android Handler,在应用程序中,我尝试每隔4秒从服务器中提取数据,并更新应用程序。 我使用的是handler,因为我每4秒调用一次AsynTask从服务器获取数据 我只是担心每4秒为AsynTask创建的实例会导致任何问题? 这就是我正在做的 private static final int DELAY = 1000 * 4; final Handler printHandler = new Handler(); private boolean keepLooping = true; printHandler.p

在应用程序中,我尝试每隔4秒从服务器中提取数据,并更新应用程序。 我使用的是handler,因为我每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);
     }
};

关于您选择的并发工具

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

最好直接使用构建AsyncTask的非常健壮的Java。如果您想重复执行此操作,请尝试。我看他们甚至为你树立了一个好榜样

或者,考虑到您的分数似乎有所下降,最好是通过一个协议(比如,有许多Java服务器和客户机)维护一个持久连接

最后,您可能想看看

一般设计问题

我知道你想经常打印分数。事实上每四秒钟一次。但关键是比分没有改变?此外,如果你的互联网连接速度很慢,八秒钟后,四秒钟前的连接还没有结束,那该怎么办?现在,您将启动另一个下载请求,即使另一个请求返回时将是最新的

解决方案是解耦下载机制和UI更新机制。一种方法是将计划下载放在单线程执行器上,这不是异步任务中可以控制的,当完成时会导致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);
走另外两条路线中的一条真的太多了,无法在一个问题的单一答案中发布。如果还没有的话,那将是另一个问题

@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");

        }

确保下一次调用仅在完成后才发送到asyc类,从而生成一个变量(
IsLoadRunning
),并在preExecute()上的
onPOstExecute
中的
false
,并添加一个条件
,如果(!IsLoadRunning){new DownloadMainScore().execute();}



服务可以更好地为您服务。查看已接受的答案

您确定在再次调用数据之前,您的数据已经更新到应用程序中查看吗?我正在更新
onPostExecute(String result)
中的UI。您最好使用该服务,保持它运行,并在每4秒钟检查一次数据,将结果调用放到handler或其他任何程序中,并更新您的视图。根据您的要求,使用Volley库将是更好的方法。每n次将您的请求添加到RequestQueue以从服务器获取数据。我将检查该库。ThankQ.Amit您是如何回答这个问题的?您刚刚发布了如何下载一个文件,这是一个非常糟糕的方法,因为OP正在尝试下载一个分数!OP询问使用异步任务是否是一个好主意“担心每4秒为AsynTask创建的实例会导致任何问题”,您可以使用GCM,这样,如果有任何新分数可用,您可以使用此方法下载新分数,并节省电池:)您在回答中说这句话的地方?这里没有这样的代码!即使你使用GCM,如果分数每四秒钟更新一次呢?那么,当您不需要保存到磁盘时,保存到磁盘也是一个非常糟糕的主意!是的,继续检查服务器端是否有任何新的可用性(如果使用asynctask或任何工作线程并每4秒执行一次),这是一个坏主意,也是一个坏主意。最好使用GCMI,我有点困惑Amit。是你告诉OP去做的:
BufferedOutputStream(新文件输出流(file))最好。谢谢汤姆,我喜欢你的解释方式。如果你能提供一段示例代码来做这件事,那就太好了。希望有帮助。另外两个选项实际上是两个宽泛的选项,以提供从头开始的示例。最好的。你在http方面听起来很有能力,所以我没有重复下载机制。我有一个疑问,ScheduledExecutorService是一个低级api,有些人说使用低级api不好!嘿,乌代。有时使用低级api并不好。但我不认为java.util.concurrent是一个低级api!它是非android java应用程序的默认选择,对于android应用程序,我们一直都在使用它。错误在于人们试图使用自己的锁和条件提供自己的并发实现。这确实是个坏消息,我怀疑人们指的是什么。最好。你是说要创建一个锁,是的,这真的很有意义。谢谢。艾哈迈德,将并发性应用到服务中也会很好。如果出于任何原因,我们无法进行某种服务器推送,您如何设想在该服务中重复下载?我尝试了IntentServices,但与AsynTask相比速度较慢。@Tom我想您必须将其与alarm manager一起使用,或创建自己的计划程序。alarm manager听起来是一个非常酷的“开箱即用”程序我有一个好主意。看看它的表现会很有趣!我也选择了某种调度器实现。可爱。
AsyncTasks should ideally be used for short operations (a few seconds at the most.)