Reputation: 93
I'm lost here. I need to read the files in a directory and make buttons from them when an app starts. I have to use a while loop, and I have to update the UI. I've tried for quite a while to run a runnable and have only the code inside the loop run in the UI thread. I'm relatively new to android, but this seemed simple enough.
This code is what I have right now. It throws no errors or warnings, but it doesn't do anything. I know the button making code works because the "add button" button makes buttons correctly. I have no idea why it isn't working. (This runs in OnCreate)
Runnable aRunnable = new Runnable() {
public void run() {
Looper.prepare();
File f = new File(Environment.getExternalStorageDirectory() + "/myapp/");
File[] filearray = f.listFiles();
int amount = filearray.length;
final String[] files = new String[amount];
int count = 0;
while (count != amount) {
files[count] = filearray[count].toString();
count += 1;
}
int times = files.length;
int counter = 0;
while (counter != times) {
Handler handler = new Handler();
handler.post(new Runnable() {
public void run() {
// Button making code
}
});
}
Looper.loop();
}
};
Thread thread = new Thread(aRunnable);
thread.start();
Upvotes: 1
Views: 244
Reputation: 31045
One problem with your existing code is that everything in the run()
method gets run on a background thread, not the main (sometimes called the UI) thread.
This is where you're creating your handler object:
Handler handler = new Handler();
This is not correct. You need to create (instantiate) the Handler
on the main thread, if using the default constructor. From the Handler docs:
public Handler ()
Added in API level 1Default constructor associates this handler with the Looper for the current thread. If this thread does not have a looper, this handler won't be able to receive messages so an exception is thrown.
So, a simple fix is simply to move that line of code earlier, into a place that you know is run on the main thread. For example, in Activity#onCreate()
:
public void onCreate(Bundle b) {
super.onCreate(b);
handler = new Handler();
}
where handler
is changed to be a member variable:
private Handler handler;
Also, just remove your Looper
calls.
See this article for more on Handler.
Another option would be to avoid using Handler
at all, and get famliar with the AsyncTask class. I personally think that's easier for new developers to use. The vogella.com link I showed also has good information on AsyncTask
.
Yet one more option would be to avoid Handler
and use the runOnUiThread() method in your Activity
to add your buttons.
Upvotes: 1
Reputation: 39846
it seems to me that you're trying to have a list of buttons based on some array. It seems that is a job for a ListView and a custom array adapter. I believe you should google some examples on it (there're billions around the internet, it's a fairly basic android pattern).
and while you're in the learning process, don't forget to check how to use for()
in Java, all those while
loops are just so ugly.
Upvotes: 0