【发布时间】:2015-12-10 13:05:03
【问题描述】:
我制作了一个 Android 应用程序,该应用程序通过 Asynctask 向服务器进行身份验证,该任务在用户按钮单击时在后台执行此操作。发生这种情况时,会向用户显示加载弹出窗口或微调器。这一切目前都在工作。
我现在正试图通过设置另一台服务器来创建冗余,以防第一台服务器出现故障。为了适应我的应用程序的这种变化,我想让 2 个异步任务一个接一个地调用。
但是,我遇到了一些问题。
作为测试 url,我一直在使用 10.255.255.1(不可路由的地址)和 www.google.com:81(阻塞的端口,丢弃的数据包)。
-
如果服务器 1 没有响应或需要很长时间(使用上面的 url 进行测试),我会尝试在 asynctask 上设置一个计时器 5-10 秒,我尝试过使用
new MyAsyncTask().execute(serverurl1).get(5000, TimeUnit.MILLISECONDS);没有用。奇怪的是,它在显示微调器之前等待了 5 秒,然后正常运行(永远等待超过 5 甚至 10 秒标记)。
-
我想这第二个问题取决于第一个问题,但是在创建第二个异步任务以查询服务器 2 之前,我如何确保第一个异步任务已完成(或已执行并超过时间限制)?我想我可以使用 STATUS.running (但只有在确保第一个异步任务已经运行之后?
对于这个,我尝试了 2 个异步任务,如下所示:
new MyAsyncTask().execute(serverurl1); new MyAsyncTask().execute(serverurl2);希望射出 2 个异步任务能让我得到某种回应。即使 1 失败了,我们仍然可以通过身份验证,但是很遗憾,它不起作用。
我知道你们中的一些人可能会说,通过序列化 asynctask 的行为,它就违背了它的目的。当应用程序与服务器进行自我检查时,我使用它在屏幕上显示微调器。
问题:
- 如果异步任务被计时器或其他事物停止/杀死,是否仍会调用 onPostExecute?我想知道如果 总是 调用第二个异步任务,这是否是放置第二个异步任务的好地方。
我理想的解决方案是:
用户点击按钮
asynctask 1 使用服务器 1 运行和查询
如果出现问题,asynctask 1 在计时器用完后被杀死
asynctask 2 然后运行查询服务器 2
如果出现问题,asynctask 2 在计时器用完后被杀死
(没有永远运行的进程并显示清除错误消息)
或
用户点击按钮
asynctask 1 使用服务器 1 运行和查询
如果出现问题,asynctask 1 在计时器用完后被杀死
然后通知用户重试(内部设置标志以查询服务器 2)
用户再次点击按钮
asynctask 2 然后运行查询服务器 2
如果出现问题,asynctask 2 在计时器用完后被杀死
(同样,没有永远运行的进程并显示清除错误消息)
谢谢。
我使用以下方法调用异步块:
private void startTask() throws IOException {
String url = "http://google.com:81";
//String url = "http://10.255.255.1";
String url2 = "someurlthatworks";
// tried this
new MyAsyncTask().execute(url);
new MyAsyncTask().execute(url2);
// and this
try {
new MyAsyncTask().execute(url).get(5000, TimeUnit.MILLISECONDS);
}catch(Exception e){}
}
我在How can I put a timer in an AsyncTask without creating another thread? 看到了这个(用我的变量编辑):
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
new MyAsyncTask.execute(url);
}
}, 5000);
它对我的问题有用吗?
这是我的异步任务代码块: 类 MyAsyncTask 扩展 AsyncTask {
@Override
protected void onPreExecute() {
super.onPreExecute();
showDialog(DIALOG_DOWNLOAD_PROGRESS);
}
@Override
protected String doInBackground(String... urls) {
int count;
InputStream input = null;
HttpURLConnection httpconnection = null;
try {
URL url = new URL(urls[0]);
httpconnection = (HttpURLConnection) url.openConnection();
httpconnection.connect();
httpconnection.setConnectTimeout(7000);
httpconnection.setReadTimeout(10000);
// check here if there is connectivity, server is accessible, http code is 200
// return error message if any of the above not found
int lengthOfFile = httpconnection.getContentLength();
input = httpconnection.getInputStream();
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
publishProgress(""+(int)((total*100)/lengthOfFile));
}
String msg = new String(data);
if(msg.contains(someinfo)) {
allow = true;
}
input.close();
} catch (Exception e) {}
return null;
}
protected void onProgressUpdate(String... progress) {
mProgressDialog.setProgress(Integer.parseInt(progress[0]));
}
@Override
protected void onPostExecute(String unused) {
dismissDialog(DIALOG_DOWNLOAD_PROGRESS);
if(allow){
Toast.makeText(getBaseContext(),"Success",Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(getBaseContext(),"Failed",Toast.LENGTH_SHORT).show();
}
}
}
据我所知
httpconnection.setConnectTimeout(7000);
httpconnection.setReadTimeout(10000);
应该可以解决我的问题,但不知何故它不起作用,asynctask 只是一直在等待。
更新:
按照 Marcin Jędrzejewski 的建议,我在连接之前移动连接和读取超时,我得到:
... [socket][1] - [socket][13] here ...
[socket][14:42141] exception
[CDS]close[42141]
close [socket][/0.0.0.0:42141]
[socket][14] connection www.google.com/4.35.153.212:81;LocalPort=59339(7000)
[CDS]connect[www.google.com/4.35.153.212:81] tm:7
[socket][15:59339] exception
[CDS]close[59339]
close [socket][/0.0.0.0:59339]
[socket][15] connection www.google.com/4.35.153.237:81;LocalPort=56148(7000)
[CDS]connect[www.google.com/4.35.153.237:81] tm:7
[socket][16:56148] exception
[CDS]close[56148]
setconnecttimeout 似乎是每次尝试连接时的超时时间,但有没有办法设置它重试连接的次数而不是总是尝试 16 次?
【问题讨论】:
-
奇怪的是, 它等了 5 秒才显示微调器……而 显然 因为
get阻塞了 main线程 -
尝试在第一个异步任务的 postExecute() 方法中执行第二个异步任务。
-
你读过这个developer.android.com/reference/android/os/…和这个:developer.android.com/reference/android/os/…,java.util.concurrent.TimeUnit)吗?
标签: android timer android-asynctask