Android Async Task在运行几次后停止运行

时间:2011-12-12 12:53:22

标签: android android-asynctask

我正在使用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,因为我也收到了这个错误(不是每次都有)。

非常感谢!

2 个答案:

答案 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();

(来自http://code.google.com/p/android-eksempler/source/browse/trunk/AndroidElementer/src/eks/asynkron/Asynkron1Thread.java?spec=svn109&r=109的例子)

答案 1 :(得分:0)

可能会发生这种情况,因为您正在同步对象“Synchronization.this”。 还注意到你没有关闭你打开的光标。