2

The goal:
Using Google App Engine server and Android client, I'm trying to put on the Google map at the Android client Users overlays. Every 30 seconds I'm polling the server and getting Vector that contains users and adding it to the map.

Current status:
I'm dong all that using in one new thread, So after running the app I got:
weird behaviors(delayed overlays, multiple overlays) and after that crushed with ConcurrentModificationException.
After reading a bit i figured out that I need to work with AsyncTask.

Correct me if I'm wrong,But I understand that everything done in the Activity at at onCreate is "running" in UIhread so I need to put the "Logic" (All the Network handling) in doInBackground and all the UI Handling like putting overlays on the map in onPostExecute.

My Question are:
1) In the current status I'm doing:

new Thread()
{
    @Override
    public void run() 
    {           
        super.run();
        while(true)
        {
            SystemClock.sleep(30000);   
            Vector responseFromServer = getUsersVectorFromServer();             
            putNewOnlineUserOnTheMap();
        }           
    }
}.start();

What is the right way to convert this To AsyncTask?
Do I poll the server still using new thread in the doInBackground or there is right way to do this?

2) Is there a specific list of what counts as UI to put in onPostExecute or any concepts list?
In my case I guess that in need to put putNewOnlineUserOnTheMap() in onPostExecute.

Thanks.

Rami
  • 2,098
  • 5
  • 25
  • 37

3 Answers3

2

Something similar to the following:

class UpdateTask extends AsyncTask<Void, Vector, Void>{

    @Override
    protected Void doInBackground(Void... params) {
        // this is running in a background thread.
        while (!isCancelled()) {
            SystemClock.sleep(30000);   
            Vector responseFromServer = getUsersVectorFromServer();
            // send the result back to the UI thread
            // onProgressUpdate will be called then
            publishProgress(responseFromServer);
        }
        return null;
    }

    @Override
    protected void onProgressUpdate(Vector... values) {
        // this is executed on the UI thread where we can safely touch UI stuff
        putNewOnlineUserOnTheMap(values[0]);
    }

}

You can't use the result of the task since the task is finished then. But you can use the progress publishing mechanism to get periodic results. If you use it like that and do the modification on the UI thread you should not get ConcurrentModificationException because you do the modifications on the one thread that can safely modify the UI.

One thing to note here: create new instances of your Vector in the background thread and then use it to update the UI. But don't touch the same object afterwards in the backgroundthread. That way you don't need any synchronization since after the background thread sends it away it is only the UI thread that touches it. (and you could use a simple ArrayList instead of a Vector)

zapl
  • 63,179
  • 10
  • 123
  • 154
1

AsyncTask uses generics and varargs.The parameters that are passed to the asyntask are . TypeOfVariableArgumentsParameters is passed into the doInBackground(), ProgressParam is used for progress information and ResultParam must be returned from doInBackground() and is passed to onPostExecute() as parameter.

example:-- protected class ParsingTask extends AsyncTask> {

     private ProgressDialog loadingDialog = new ProgressDialog(JsonParserActivity.this);



     protected void onPreExecute() {
         loadingDialog.setMessage("loading app store..");
         loadingDialog.show();
     }

    @Override
    protected ArrayList<Items> doInBackground( Context... params )  {

        // do ur process here.
        return result;
     }      

        if (!this.isCancelled()) {
        }

        return result;
    }

    @Override
    protected void onProgressUpdate(String... s)   {
        super.onProgressUpdate(s);
        Toast.makeText(getApplicationContext(), s[0], Toast.LENGTH_SHORT).show();
    }

    @Override
    protected void onPostExecute( ArrayList<Items> response )  {
    //if u r dealing with list view and adapters set the adapter here at the onPostExecute()
            loadingDialog.dismiss();

    }

    @Override
    protected void onCancelled() {
        super.onCancelled();

        Toast.makeText(getApplicationContext(), "The operation was cancelled", 1).show();
    }

}
Ragesh Gopal
  • 79
  • 2
  • 10
0

You can use AsyncTask like below. Hope this will help you..

Class YourClass{
    void YourClass(){
       NetworkTask nT = new NetworkTasK();
       nT.execute();
    }
}
protected class NetworkTask extends AsyncTask<Void, String, Boolean>
{
    @Override
    protected Boolean doInBackground(Void... params) 
    {
        try 
        {
            String response;
            while(keepreceiving)
            {
                response = in.readLine();//Prog Counter stops here until getting i/p.

                if(response != null)
                    yourFunctionForResponse(response);
            }
        }

        catch (Exception ex) 
        {

        }
        return null;        
    }
     private void yourFunctionForResponse(String response){
     //things to do....
     }
}

You may also try runOnUiThread(Runnable action) along with this to implement your work.

Arun Chettoor
  • 1,021
  • 1
  • 12
  • 17