Android 在无限循环中调用AsyncTask从服务器提取数据是一种好方法吗?
在应用程序中,我尝试每隔4秒从服务器中提取数据,并更新应用程序。 我使用的是handler,因为我每4秒调用一次AsynTask从服务器获取数据 我只是担心每4秒为AsynTask创建的实例会导致任何问题? 这就是我正在做的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
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.)