Android Async Task перестает работать после запуска несколько раз - PullRequest
2 голосов
/ 12 декабря 2011

Я использую 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 ]

1 голос
/ 12 декабря 2011

Я думаю, что ваш doInBackground () зависает. Сделайте выписку из журнала, когда она введена, а когда выйдет, и проверьте.

В старые времена AsyncTask имел пул потоков, поэтому, если doInBackground () зависал, то это не влияло на другие AsyncTasks. Это изменило AFAIK с Android 2.2 или 2.3 до того, что один поток позаботился обо всех AyncTasks, по одному за раз. Поэтому, если ваш doInBackground () зависает, это может повлиять на следующие запускаемые AsyncTasks и будет зависать сразу после onPreExecute ().

Редактировать: оно было изменено с одного потока на несколько, а затем обратно на один поток: http://developer.android.com/reference/android/os/AsyncTask.html#execute%28Params...%29 "При первом представлении AsyncTasks выполнялись последовательно в одном фоновом потоке. Начиная с DONUT, это было изменено на пул потоков, позволяющий нескольким задачам работать параллельно. После HONEYCOMB планируется изменить это вернуться к одному потоку, чтобы избежать распространенных ошибок приложения, вызванных параллельным выполнением. "

Если вы действительно хотите, чтобы неопределенное количество вещей "зависало" в parralel, не используйте AsyncTask. Используйте старые добрые потоки, которые, когда им нужно обновить GUI, запускают Runnable для запуска в потоке GUI:

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)

0 голосов
/ 12 декабря 2011

Это может произойти, потому что вы синхронизируете объект "Synchronization.this". Также заметили, что вы не закрываете курсор, который открыли.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...