Hi Everyone, After digging with the APIs I still cannot figure out how the AsyncTask properly works and why some behavior occur.
I'm trying to achieve one contact list that can be updated from a background async task very frequently. There are situations where invoking UI updates from the background thread just freeze the UI as you see in example #2. or make the list not to react properly to finger as a regular contact list. Can anyone give me some hint on how to achieve the expected behavior? I added here the activities that form my project (sorry for the lenght of the post, my idea was to share the complete problem with everyone) Example 1: Contact list without background task. This code contains the behavior of a default contact list. This code produce the expected behavior in responsive for the user but do not update. This activity shows the ideal response for a contact list. package com.pp.lists; import android.app.ListActivity; import android.content.Intent; import android.hardware.SensorManager; import android.os.Bundle; import android.view.View; import android.widget.ArrayAdapter; import android.widget.Button; public class List1 extends ListActivity implements View.OnClickListener { Button btnBack = null; SensorManager sensorManager = null; String[] items = { "lorem", "ipsum", "dolor", "sit", "amet", "consectetuer", "adipiscing", "elit", "morbi", "vel", "ligula", "vitae", "arcu", "aliquet", "mollis", "etiam", "vel", "erat", "placerat", "ante", "porttitor", "sodales", "pellentesque", "augue", "purus", "lorem", "ipsum", "dolor", "sit", "amet", "consectetuer", "adipiscing", "elit", "morbi", "vel", "ligula", "vitae", "arcu", "aliquet", "mollis", "etiam", "vel", "erat", "placerat", "ante", "porttitor", "sodales", "pellentesque", "augue", "purus", "lorem", "ipsum", "dolor", "sit", "amet", "consectetuer", "adipiscing", "elit", "morbi", "vel", "ligula", "vitae", "arcu", "aliquet", "mollis", "etiam", "vel", "erat", "placerat", "ante", "porttitor", "sodales", "pellentesque", "augue", "purus", "lorem", "ipsum", "dolor", "sit", "amet", "consectetuer", "adipiscing", "elit", "morbi", "vel", "ligula", "vitae", "arcu", "aliquet", "mollis", "etiam", "vel", "erat", "placerat", "ante", "porttitor", "sodales", "pellentesque", "augue", "purus" }; /** Called when the activity is first created. */ @Override public void onCreate( Bundle savedInstanceState ) { super.onCreate(savedInstanceState); setContentView(R.layout.listdemo); setListAdapter(new ArrayAdapter<String>(this, R.layout.listitem, R.id.label, items)); btnBack = (Button) findViewById(R.id.btnBackFromList); btnBack.setOnClickListener(this); } public void onClick( View arg0 ) { if ( btnBack == arg0 ) { startActivity(new Intent(this, Main.class)); } } public void onResume() { System.out.println("List1.onResume!"); super.onResume(); } public void onPause() { System.out.println("List1.onPause!"); super.onPause(); } } Example 2: This example update the contact list very frequently properly but without freezing DO NOT allow the user to even scroll. package com.pp.lists; import android.app.ListActivity; import android.content.Intent; import android.os.AsyncTask; import android.os.Bundle; import android.os.Handler; import android.view.View; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.EditText; import android.widget.ListView; public class List2 extends ListActivity implements View.OnClickListener { Button btnBack = null; Handler handler = new Handler(); String[] items = { "lorem", "ipsum", "dolor", "sit", "amet", "consectetuer", "adipiscing", "elit", "morbi", "vel", "ligula", "vitae", "arcu", "aliquet", "mollis", "etiam", "vel", "erat", "placerat", "ante", "porttitor", "sodales", "pellentesque", "augue", "purus", "lorem", "ipsum", "dolor", "sit", "amet", "consectetuer", "adipiscing", "elit", "morbi", "vel", "ligula", "vitae", "arcu", "aliquet", "mollis", "etiam", "vel", "erat", "placerat", "ante", "porttitor", "sodales", "pellentesque", "augue", "purus", "lorem", "ipsum", "dolor", "sit", "amet", "consectetuer", "adipiscing", "elit", "morbi", "vel", "ligula", "vitae", "arcu", "aliquet", "mollis", "etiam", "vel", "erat", "placerat", "ante", "porttitor", "sodales", "pellentesque", "augue", "purus", "lorem", "ipsum", "dolor", "sit", "amet", "consectetuer", "adipiscing", "elit", "morbi", "vel", "ligula", "vitae", "arcu", "aliquet", "mollis", "etiam", "vel", "erat", "placerat", "ante", "porttitor", "sodales", "pellentesque", "augue", "purus" }; private ArrayAdapter adapter = null; private ListView list = null; BGSorter task = null; EditText txtTest = null; public boolean isRunning = true; /** Called when the activity is first created. */ @Override public void onCreate( Bundle savedInstanceState ) { super.onCreate(savedInstanceState); setContentView(R.layout.listdemo); adapter = new ArrayAdapter<String>(this, R.layout.listitem, R.id.label, items); setListAdapter(adapter); btnBack = (Button) findViewById(R.id.btnBackFromList); btnBack.setOnClickListener(this); list = this.getListView(); } public void onClick( View arg0 ) { if ( btnBack == arg0 ) { startActivity(new Intent(this, Main.class)); } } public void onResume() { WorkingObject.status = true; // Start BG job System.out.println("List2.onResume!"); task = new BGSorter(); task.execute(); super.onResume(); } public void onPause() { System.out.println("List2.onPause!"); WorkingObject.status = false; task.cancel(true); super.onPause(); } class BGSorter extends AsyncTask<Void, String, Void> { @Override protected void onProgressUpdate( String... args ) { try { System.out.println("OnProgressUpdate=" + Thread.currentThread().getName()); list.invalidateViews(); } catch ( Exception e ) { System.out.println(e.toString()); } } @Override protected Void doInBackground( Void... arg0 ) { System.out.println("DoBackground=" + Thread.currentThread ().getName()); int random1 = (int) (Math.random() * 10000 % 10); // items.length); int random2 = (int) (Math.random() * 10000 % 10); // items.length); String temp = items[random1]; items[random1] = items[random2]; items[random2] = temp; publishProgress("random1=" + random1 + " random2=" + random2); return null; } @Override protected void onPostExecute( Void result ) { // TODO Auto-generated method stub super.onPostExecute(result); System.out.println(isCancelled()); // Launch another copy of the thread // if ( isRunning ) { if ( WorkingObject.status ) { task = new BGSorter(); task.execute(); } } } class Holder { public int position = 0; } class UpdateList implements Runnable { @Override public void run() { System.out.println("UpdateList=" + Thread.currentThread ().getName()); list.invalidateViews(); } } } EXAMPLE 3: Allow the user to interact and scroll but not to 100% accurately. You can see the difference between example 3 and 1 in result. Here, you will see that after start the scrolling with the finger, the list do not respond properly if you try to stop the scroll as in sample #1. Can anyone give me an idea why? package com.pp.lists; import android.app.ListActivity; import android.content.Intent; import android.hardware.SensorManager; import android.os.AsyncTask; import android.os.Bundle; import android.os.Handler; import android.view.View; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.EditText; import android.widget.ListView; public class List3 extends ListActivity implements View.OnClickListener { Button btnBack = null; Handler handler = new Handler(); String[] items = { "lorem", "ipsum", "dolor", "sit", "amet", "consectetuer", "adipiscing", "elit", "morbi", "vel", "ligula", "vitae", "arcu", "aliquet", "mollis", "etiam", "vel", "erat", "placerat", "ante", "porttitor", "sodales", "pellentesque", "augue", "purus", "lorem", "ipsum", "dolor", "sit", "amet", "consectetuer", "adipiscing", "elit", "morbi", "vel", "ligula", "vitae", "arcu", "aliquet", "mollis", "etiam", "vel", "erat", "placerat", "ante", "porttitor", "sodales", "pellentesque", "augue", "purus", "lorem", "ipsum", "dolor", "sit", "amet", "consectetuer", "adipiscing", "elit", "morbi", "vel", "ligula", "vitae", "arcu", "aliquet", "mollis", "etiam", "vel", "erat", "placerat", "ante", "porttitor", "sodales", "pellentesque", "augue", "purus", "lorem", "ipsum", "dolor", "sit", "amet", "consectetuer", "adipiscing", "elit", "morbi", "vel", "ligula", "vitae", "arcu", "aliquet", "mollis", "etiam", "vel", "erat", "placerat", "ante", "porttitor", "sodales", "pellentesque", "augue", "purus" }; private ArrayAdapter adapter = null; private ListView list = null; BGSorter task = null; EditText txtTest = null; public boolean isRunning = true; /** Called when the activity is first created. */ @Override public void onCreate( Bundle savedInstanceState ) { super.onCreate(savedInstanceState); setContentView(R.layout.listdemo); adapter = new ArrayAdapter<String>(this, R.layout.listitem, R.id.label, items); setListAdapter(adapter); btnBack = (Button) findViewById(R.id.btnBackFromList); btnBack.setOnClickListener(this); list = this.getListView(); } public void onClick( View arg0 ) { if ( btnBack == arg0 ) { startActivity(new Intent(this, Main.class)); } } public void onResume() { // Start BG job System.out.println("List2.onResume!"); task = new BGSorter(); task.execute(); super.onResume(); } public void onPause() { System.out.println("List2.onPause!"); task.cancel(true); super.onPause(); } class BGSorter extends AsyncTask<Void, String, Void> { @Override protected void onProgressUpdate( String... args ) { try { System.out.println("OnProgressUpdate=" + Thread.currentThread().getName()); list.invalidateViews(); } catch ( Exception e ) { System.out.println(e.toString()); } } @Override protected Void doInBackground( Void... arg0 ) { while ( !isCancelled() ) { System.out.println("DoBackground=" + Thread.currentThread().getName()); int random1 = (int) (Math.random() * 10000 % 10); // items.length); int random2 = (int) (Math.random() * 10000 % 10); // items.length); String temp = items[random1]; items[random1] = items[random2]; items[random2] = temp; publishProgress("random1=" + random1 + " random2=" + random2); } return null; } } class Holder { public int position = 0; } class UpdateList implements Runnable { @Override public void run() { System.out.println("UpdateList=" + Thread.currentThread ().getName()); adapter.notifyDataSetChanged(); } } } Thanks for the time. I'will be more than glad to receive your feedback. Pablo --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Android Developers" group. To post to this group, send email to android-developers@googlegroups.com To unsubscribe from this group, send email to android-developers-unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/android-developers?hl=en -~----------~----~----~----~------~----~------~--~---