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 <hunt1...@gmail.com> 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 > MediaStore.Audio.Media.ARTIST, > // 1 artist > MediaStore.Audio.Media.TITLE, > // 2 song > MediaStore.Audio.Media.DATA, > // 3 full path of file "/sdcard/In > Da Club.mp3" > MediaStore.Audio.Media.DISPLAY_NAME, // 4 > "In Da Club.mp3" > MediaStore.Audio.Media.DURATION}; > // 5 time in milliseconds > > String selection = MediaStore.Audio.Media.IS_MUSIC + > " != 0"; > Cursor c = this.managedQuery(media, projection, > selection, null, > null); > > db_songs.open(); > db_songs.deletePlaylist(pl); // delete all songs > in playlist first > if (c.moveToFirst()){ > do { > db_songs.insertPoint( > pl, > c.getString(1), > c.getString(2), > c.getString(3), > c.getString(4), > c.getString(5), > 0); > }while (c.moveToNext()); > } > resultCount = c.getCount(); > db_songs.close(); > c.close(); > Toast.makeText(ListingThing.this, > "All songs on the SD card where > added to the playlist > '"+playlistName+"'", > Toast.LENGTH_LONG).show(); > > }catch(Exception e){ > Toast.makeText(ListingThing.this, > "Error loading all songs to playlist.\n: > "+e, > Toast.LENGTH_LONG).show(); > } > > } > } > > > -- > 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<android-developers%2bunsubscr...@googlegroups.com> > For more options, visit this group at > http://groups.google.com/group/android-developers?hl=en -- 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