views:

970

answers:

2

Hi, I've been trying to get my progress bar view to work in my file scanner application, and I'm thoroughly stumped by the proper combination of Activities, Services, Threads, and Handlers.

Here's the structure: My Activity contains a Horizontal-styled ProgressBar. On menu item click, I spawn a Service which, onCreate(), which is where I want to be able to update the progress bar.

My question: what am I missing?

  1. Activity "a" (with ProgressBar)
          2. "a".onOptionsItemSelected(): Spawn Service "b"
                   3. "b".onCreate(): Control the ProgressBar in "a" // here is where I have my trouble

Layout for Progress Bar (1):

<ProgressBar 
 style="?android:attr/progressBarStyleHorizontal"
 android:layout_height="wrap_content"
 android:max="100"
 android:progress="0"
 android:secondaryProgress="0" 
 android:layout_width="300px" 
 android:layout_marginLeft="10px" 
 android:id="@+id/progress_horizontal"
 />

"a".onOptionsItemSelected (2):

public boolean onOptionsItemSelected(MenuItem item) 
{
      if (svc == null)
      {
       android.util.Log.v("@@@@@@@@@@@@@@@@@@@@@", "starting");
       svc = new Intent(this, DoScan.class);
       // done in "a".onCreate()
                            // hmap = new HashMap();
                 // hmap.put("tv", tv);
       svc.putExtra("hmap", hmap);
       startService(svc);
      }
      break;
}

"b".onCreate() (3):

@Override
public void onCreate() {
 super.onCreate();

 //startThread();
 TextView tv = (TextView) Peekaboo.hmap.get("tv");
 tv.append("cocktail");
}
A: 

To be blunt, your service's onCreate() is...problematic:

  1. Don't try to pass widgets to a service
  2. Don't try to modify widgets from a service
  3. Do try to use background threads when working with progress bars

In terms of #1 and #2, ask yourself what will happen when the user rotates the screen (e.g., slides out the G1's keyboard), and the widgets the service is holding become invalid.

In terms of #3, starting a local service does not automatically create a background thread. The service will run on the same thread as the activity and all other activities. If you want work to be done on a background thread, use AsyncTask or create a thread and use a Handler or post() or postDelayed() or runOnUiThread() to have the background thread arrange for UI updates to occur on the UI thread.

CommonsWare
A: 

Without doing anything special your program runs in one thread, the UI thread, the OS's UI thread. Anything done in your program is running in the UI thread unless you create another thread for it to run in. That thread needs to communicate the task's progress back to the UI thread (use Runnable, Handler, and Thread classes). Then the main UI thread updates what the user sees on the ProgressBar.

This best thing to do is take an hour and work through the SDK thread examples.

Good places to start are here and here.

Will