1

我在这里迷路了。我需要在应用程序启动时读取目录中的文件并从中制作按钮。我必须使用 while 循环,并且必须更新 UI。我已经尝试了很长一段时间来运行一个可运行文件,并且只有循环内的代码在 UI 线程中运行。我对 android 比较陌生,但这似乎很简单。

这段代码就是我现在所拥有的。它不会抛出任何错误或警告,但它什么也不做。我知道按钮制作代码有效,因为“添加按钮”按钮可以正确制作按钮。我不知道为什么它不起作用。(这在 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();
4

2 回答 2

1

现有代码的一个问题是该run()方法中的所有内容都在后台线程上运行,而不是在主线程(有时称为UI)上运行。

这是您创建处理程序对象的地方:

        Handler handler = new Handler();

这是不正确的。如果使用默认构造函数,您需要Handler在主线程上创建(实例化)。从处理程序文档

public Handler ()在 API 级别 1 中添加

默认构造函数将此处理程序与当前线程的 Looper 相关联。如果该线程没有 Looper,则该处理程序将无法接收消息,因此会引发异常。

所以,一个简单的修复就是将那行代码更早地移动到你知道在主线程上运行的地方。 例如,在Activity#onCreate()

public void onCreate(Bundle b) {
   super.onCreate(b);

   handler = new Handler();
}

wherehandler改为成员变量:

private Handler handler;

另外,只需删除您的Looper电话。

有关 Handler 的更多信息,请参阅本文

其他选项

另一种选择是完全避免使用Handler,并熟悉AsyncTask 类。我个人认为这对于新开发人员来说更容易使用。我展示的 vogella.com 链接也有关于AsyncTask.

还有一种选择是避免Handler使用runOnUiThread()方法Activity来添加按钮。

于 2013-09-01T22:21:02.600 回答
0

在我看来,您正试图拥有一个基于某个数组的按钮列表。这似乎是 ListView 和自定义数组适配器的工作。我相信你应该用谷歌搜索一些例子(互联网上有数十亿,这是一个相当基本的 android 模式)。

在学习过程中,不要忘记检查如何for()在 Java 中使用,所有这些while循环都非常丑陋。

于 2013-09-01T22:07:23.550 回答