Re: [android-developers] Can't show ProgressDialog during listview update

2010-02-18 Thread Frank Weiss
Use AsyncTask instead od Java threads. I'm not kidding, it's that simple.

On Thu, Feb 18, 2010 at 10:21 AM, Ken H  wrote:

> What am I doing wrong here? I have a listview of items (songs on the
> sd card). The user has an option to load all the songs on the sd card
> to into a current playlist -- those songs are what is displayed in the
> listview. Because this can take few seconds to load if they have a lot
> of songs on the card, I want to display a progress dialog to just tell
> the user "One moment..." until the list refresh is done.
>
> I launch a thread to do this. I've done this successfully on another
> app I have (which just updates a database in the background but
> doesn't update any display), but this one fails with this error
> message, "Can't create handler inside thread that has not called
> Looper.prepare()". I chopped down the activity and pasted it below.
> What am I doing wrong here? I have just a vague idea of what might be
> happening.
>
> By the way, everything works when I take out the threaded stuff, it
> just looks like the app freezes for a couple seconds.
>
> Ken
>
> /
>
> /
>
> public class ListingThing extends ListActivity implements Runnable {
>public static final String PREF_NAME = "PlaylistAlarmPreferences";
>static final private int CONFIGURE_PLAYLIST = Menu.FIRST;
>static final private int DELETE_LIST = Menu.FIRST+1;
>static final private int DELETE_SONG = Menu.FIRST;
>static final private int LOAD_ALL = Menu.FIRST+2;
>String playlistName, CURRENT_PLAYLIST;
>SharedPreferences settings;
>String[] items, subitems, fullpath;
>int DRILL_DOWN_LEVEL, resultCount;
>MediaPlayer mMediaPlayer;
>ProgressDialog myProgressDialog;
>
>/** Called when the activity is first created. */
>@Override
>public void onCreate(Bundle savedInstanceState) {
>super.onCreate(savedInstanceState);
>
>mMediaPlayer = new MediaPlayer();
>
>getListOfPlaylists();
>setListAdapter(new MySpecialAdapter(this));
>// you need this for the contextmenu
>registerForContextMenu(getListView());
>}
>
>public void getListOfPlaylists(){
>// query db for list of songs
>}
>
>class MySpecialAdapter extends ArrayAdapter {
>Activity context;
>
>MySpecialAdapter(Activity context) {
>super(context, R.layout.double_list_item, items);
>this.context=context;
>}
>
>public View getView(int position, View convertView, ViewGroup
> parent) {
>View row=convertView;
>
>if (row==null) {
>LayoutInflater inflater=context.getLayoutInflater();
>row=inflater.inflate(R.layout.double_list_item,
> null);
>}
>
>TextView text1 = (TextView)row.findViewById(R.id.maintext);
>text1.setText(items[position]);
>TextView text2 = (TextView)row.findViewById(R.id.subtext);
>text2.setText(subitems[position]);
>row.setSoundEffectsEnabled(true);
>
>return row;
>}
>}
>
>// This handles a context menu item click
>@Override
>public boolean onContextItemSelected(MenuItem item) {
>AdapterContextMenuInfo info = (AdapterContextMenuInfo)
> item.getMenuInfo();
>Object n = this.getListAdapter().getItemId((int)info.id);
>final String pos = n.toString();// get the item number of
> selection
>
>myProgressDialog = ProgressDialog.show(this,
>  "One moment...", "Refreshing list of songs in
> playlist.", true);
>CURRENT_PLAYLIST = items[Integer.parseInt(pos)];
>Thread t = new Thread(this);
>t.start();
>
>return super.onContextItemSelected(item);
>}
>
>public void run(){
>loadsongs(CURRENT_PLAYLIST);
>handler.sendEmptyMessage(0);
>}
>
>private Handler handler = new Handler() {
>@Override
>public void handleMessage(Message msg){
>myProgressDialog.dismiss();
>// refresh the listing of playlists
>getListOfPlaylists();
>setListAdapter(new MySpecialAdapter(ListingThing.this));
>
>}
>};
>
>// delete all songs in playlist and then reload all songs into it
>private void loadsongs(String pl){
>try{
>Uri media =
> MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
>DBAdapter db_songs = new
> DBAdapter(ListingThing.this);
>
>String[] projection = {
> // The columns we want
>MediaStore.Audio.Media._ID,
> // 0
>MediaSt

[android-developers] Can't show ProgressDialog during listview update

2010-02-18 Thread Ken H
What am I doing wrong here? I have a listview of items (songs on the
sd card). The user has an option to load all the songs on the sd card
to into a current playlist -- those songs are what is displayed in the
listview. Because this can take few seconds to load if they have a lot
of songs on the card, I want to display a progress dialog to just tell
the user "One moment..." until the list refresh is done.

I launch a thread to do this. I've done this successfully on another
app I have (which just updates a database in the background but
doesn't update any display), but this one fails with this error
message, "Can't create handler inside thread that has not called
Looper.prepare()". I chopped down the activity and pasted it below.
What am I doing wrong here? I have just a vague idea of what might be
happening.

By the way, everything works when I take out the threaded stuff, it
just looks like the app freezes for a couple seconds.

Ken

/
/

public class ListingThing extends ListActivity implements Runnable {
public static final String PREF_NAME = "PlaylistAlarmPreferences";
static final private int CONFIGURE_PLAYLIST = Menu.FIRST;
static final private int DELETE_LIST = Menu.FIRST+1;
static final private int DELETE_SONG = Menu.FIRST;
static final private int LOAD_ALL = Menu.FIRST+2;
String playlistName, CURRENT_PLAYLIST;
SharedPreferences settings;
String[] items, subitems, fullpath;
int DRILL_DOWN_LEVEL, resultCount;
MediaPlayer mMediaPlayer;
ProgressDialog myProgressDialog;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

mMediaPlayer = new MediaPlayer();

getListOfPlaylists();
setListAdapter(new MySpecialAdapter(this));
// you need this for the contextmenu
registerForContextMenu(getListView());
}

public void getListOfPlaylists(){
// query db for list of songs
}

class MySpecialAdapter extends ArrayAdapter {
Activity context;

MySpecialAdapter(Activity context) {
super(context, R.layout.double_list_item, items);
this.context=context;
}

public View getView(int position, View convertView, ViewGroup
parent) {
View row=convertView;

if (row==null) {
LayoutInflater inflater=context.getLayoutInflater();
row=inflater.inflate(R.layout.double_list_item, null);
}

TextView text1 = (TextView)row.findViewById(R.id.maintext);
text1.setText(items[position]);
TextView text2 = (TextView)row.findViewById(R.id.subtext);
text2.setText(subitems[position]);
row.setSoundEffectsEnabled(true);

return row;
}
}

// This handles a context menu item click
@Override
public boolean onContextItemSelected(MenuItem item) {
AdapterContextMenuInfo info = (AdapterContextMenuInfo)
item.getMenuInfo();
Object n = this.getListAdapter().getItemId((int)info.id);
final String pos = n.toString();// get the item number of
selection

myProgressDialog = ProgressDialog.show(this,
  "One moment...", "Refreshing list of songs in
playlist.", true);
CURRENT_PLAYLIST = items[Integer.parseInt(pos)];
Thread t = new Thread(this);
t.start();

return super.onContextItemSelected(item);
}

public void run(){
loadsongs(CURRENT_PLAYLIST);
handler.sendEmptyMessage(0);
}

private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg){
myProgressDialog.dismiss();
// refresh the listing of playlists
getListOfPlaylists();
setListAdapter(new MySpecialAdapter(ListingThing.this));

}
};

// delete all songs in playlist and then reload all songs into it
private void loadsongs(String pl){
try{
Uri media = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
DBAdapter db_songs = new DBAdapter(ListingThing.this);

String[] projection = { 
// The columns we want
MediaStore.Audio.Media._ID, 
// 0
MediaStore.Audio.Media.ARTIST,  
// 1 artist
MediaStore.Audio.Media.TITLE,   
// 2 song
MediaStore.Audio.Media.DATA,
// 3 full p