我正在使用AsyncTask通过互联网下载数据,我遇到了一些问题。我需要能够启动一次AsyncTask几次,这就是我每次创建一个新实例的原因,但我注意到的事情是它在前三到四次没有任何问题,但之后我的AsyncTask是坚持onPreExecute()
并在此之后无所事事。难道我做错了什么 ? (实际上我只是出于测试目的而一个接一个地使用两个AsyncTasks)。以下是我正在使用的示例代码:
这就是我启动AsyncTasks的方式:
if (index == 1) {
//Login - first way
new FirstSync().execute(Synchronization.this);
} else if (index == 2) {
//SyncWithHash - second way
SyncWithHash syncHash = new SyncWithHash();
syncHash.execute(Synchronization.this);
} else if (index == 3) {
//Deactivate Collection - third way
deactivateColl = new DeactivateCollection();
deactivateColl.execute(Synchronization.this);
}
我尝试了三种不同的方式来启动asyncTask,但没有改变。这是我的AsyncTask:
// Sync With Hash
public class SyncWithHash extends AsyncTask <Context, Integer, Void> {
@Override
protected Void doInBackground(Context... arrContext) {
try {
String charset = "UTF-8";
hash = getAuthHash();
SharedPreferences lastUser = PreferenceManager.getDefaultSharedPreferences(Synchronization.this);
int userId = lastUser.getInt("lastUser", 1);
systemDbHelper = new SystemDatabaseHelper(Synchronization.this, null, 1);
systemDbHelper.initialize(Synchronization.this);
String sql = "SELECT dbTimestamp FROM users WHERE objectId=" + userId;
Cursor cursor = systemDbHelper.executeSQLQuery(sql);
if (cursor.getCount() < 0) {
cursor.close();
} else if (cursor.getCount() > 0) {
cursor.moveToFirst();
timeStamp = cursor.getString(cursor.getColumnIndex("dbTimestamp"));
Log.d("", "timeStamp : " + timeStamp);
}
String query = String.format("debug_data=%s&"
+ "client_auth_hash=%s&" + "timestamp=%s&"
+ "client_api_ver=%s&"
+ "set_locale=%s&" + "device_os_type=%s&"
+ "device_sync_type=%s&"
+ "device_identification_string=%s&"
+ "device_identificator=%s&" + "device_resolution=%s",
URLEncoder.encode("1", charset),
URLEncoder.encode(hash, charset),
URLEncoder.encode(timeStamp, charset),
URLEncoder.encode(clientApiVersion, charset),
URLEncoder.encode(locale, charset),
URLEncoder.encode(version, charset),
URLEncoder.encode("14", charset),
URLEncoder.encode(version, charset),
URLEncoder.encode(deviceId, charset),
URLEncoder.encode(resolution, charset));
SharedPreferences useSSLConnection = PreferenceManager
.getDefaultSharedPreferences(Synchronization.this);
boolean useSSl = useSSLConnection.getBoolean("UseSSl", true);
if (useSSl) {
UseHttpsConnection(url, charset, query);
} else {
UseHttpConnection(url, charset, query);
}
} catch (Exception e2) {
e2.printStackTrace();
}
return null;
}
@Override
protected void onProgressUpdate(Integer... progress) {
//cancelDialog.setProgress(progress[0]);
}
@Override
protected void onCancelled() {
Log.d("","ON CANCELLED");
}
@Override
protected void onPreExecute()
{
Log.d("","ON PRE EXECUTE");
// myProgress = 0;
}
@Override
protected void onPostExecute(Void v) {
Log.d("","ON POST EXECUTE");
}
}
所以任何想法为什么会发生,哪些是能够使用AsyncTask几次没有任何异常和错误的最佳方式,就像我得到的那样。
还有一个问题:AsyncTask中有什么东西可以导致我的连接成为Reset by peer
,因为我也收到了这个错误(不是每次都有)。
非常感谢!
答案 0 :(得分:1)
我认为你的doInBackground()正在挂起。在输入时和退出时生成日志语句并检查。
在过去AsyncTask有一个线程池,所以如果doInBackground()挂起,那么它不会影响其他AsyncTasks。这改变了使用Android 2.2或2.3的AFAIK,单个线程一次一个地处理所有AyncTasks。因此,如果你的doInBackground()挂起,它可能会影响正在启动的下一个AsyncTasks,并且会在onPreExecute()之后立即挂起。
编辑:它从单个线程更改为多个,然后再更改为单个线程: http://developer.android.com/reference/android/os/AsyncTask.html#execute%28Params...%29“首次引入时,AsyncTasks在一个后台线程上串行执行。从DONUT开始,这被改为一个线程池,允许多个任务并行运行。在HONEYCOMB之后,计划将其更改回来到一个线程,以避免由并行执行引起的常见应用程序错误。“
如果确实想要在parralel中“挂起”无限量的东西,那么就不要使用AsyncTask。使用好的旧线程,当需要更新GUI时,触发要在GUI线程上运行的Runnable:
Button knap1, knap2, knap3;
...
Runnable r=new Runnable() {
public void run() {
// Do some stuff than hangs
try { Thread.sleep(10000); } catch (InterruptedException ex) {}
System.out.println("færdig!");
// Update GUI thread
Runnable r2=new Runnable() {
public void run() {
knap3.setText("færdig!");
}
};
runOnUiThread(r2);
}
};
new Thread(r).start();
答案 1 :(得分:0)
可能会发生这种情况,因为您正在同步对象“Synchronization.this”。 还注意到你没有关闭你打开的光标。