2

I'm using using AsyncTask to download data over internet and I have a little problem. I need to be able to start one AsyncTask a few times, that's why I'm creating a new instance everytime,but the thing that I notice is that it's working without any problem the first three or four times,but after that my AsyncTask is stuck on onPreExecute() and doing nothing after that. Am I doing something wrong ? (Actually I am using two AsyncTasks one after another just for testing purposes). Here is the sample code which I'm using :

this is how I start the 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);
    }

I did try with three different ways to start the asyncTask,but no change. Here is my 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");
    }
  }

So any ideas why it's happening and which is the best way to be able to use an AsyncTask a few times without any exceptions and bugs like the one that I get.

And another question : Is there anything in AsyncTask which can cause my connection to be Reset by peer , because I'm getting this error too (not every time).

Thanks a lot!

Android-Droid
  • 14,365
  • 41
  • 114
  • 185
  • Hello Bombastic, Have you noticed if any of your asynk threads get a response from the server ? – R.daneel.olivaw Dec 12 '11 at 13:37
  • Actually every asynctask gets teh response in the beginning, but after a few runs they stay stuck in `onPreExecute`, not even show the logs from `doInBackground` in the beginning. – Android-Droid Dec 12 '11 at 13:40
  • Could you explain what is `getDefaultSharedPreferences(Synchronization.this)` you are using in your questions ? – Mr_and_Mrs_D Aug 03 '13 at 15:55

2 Answers2

1

I think your doInBackground() is hanging. Make log statement when its entered and when its exited and check.

In the old days AsyncTask had a pool of threads, so if a doInBackground() hung, then it didnt affect the other AsyncTasks. That changed AFAIK with Android 2.2 or 2.3 to that a single thread took care of all AyncTasks, one at a time. Therefore, if your doInBackground() is hanging it might affect the next AsyncTasks being started and the will hang right after onPreExecute().

Edit: It was changed from a single thread, to multiple, and then back to a single thread: http://developer.android.com/reference/android/os/AsyncTask.html#execute%28Params...%29 "When first introduced, AsyncTasks were executed serially on a single background thread. Starting with DONUT, this was changed to a pool of threads allowing multiple tasks to operate in parallel. After HONEYCOMB, it is planned to change this back to a single thread to avoid common application errors caused by parallel execution."

If you really want an indefinite lot of stuff to 'hang' in parralel, then don't use AsyncTask. Use good old threads, which, when they need to update the GUI, fire off a Runnable to be runned on the GUI thread:

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

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

Jacob Nordfalk
  • 3,533
  • 1
  • 21
  • 21
  • You know any way which can help me to fix that when it's happend? – Android-Droid Dec 12 '11 at 13:49
  • Best would be to change your code so that network operations time out after some time. Its inside your UseHttpsConnection() and UseHttpConnection(), which you didnt post that the change needs to be made. If you use HttpURLConnection, then make a setConnectTimeout(10000); to make it time out after 10 secs. If you *really* want an indefinite lot of stuff to 'hang' in parralel, then don't use AsyncTask. Use good old threads, and see my sample code above – Jacob Nordfalk Dec 13 '11 at 08:53
  • Actually this is the way which I changed my AsyncTask - using Threads now, so thank you for your answer! I've already did it. – Android-Droid Dec 13 '11 at 09:06
0

It might be happening because you are synchronizing on an object "Synchronization.this'. Also noticed you are not closing the cursor which you opened.

Rajdeep Dua
  • 11,190
  • 2
  • 32
  • 22