Android FileObserver的onEvent方法没有被调用

3

有人能帮我解决这个问题吗?

我想观察一个文件是否被修改,以便更新活动。经过几次测试,我已经确定它根本没有起作用。我做错了什么吗?

我正在创建一个FileObserver,并使用onEvent方法显示Toast和记录数据,只为了看看它是否起作用,但是onEvent从未被调用过。我尝试了现有文件和新文件,但无论哪种情况都不起作用。

    Context context = this;
    File fileFolder = context.getFilesDir();

    String fileName = "quest";
    FileObserver questObserver = new FileObserver(fileFolder.getPath()) { // also tried fileFolder.getName()
        @Override
        public void onEvent(int event, String path) {
            Toast.makeText(getApplicationContext(), "onEvent fired", Toast.LENGTH_LONG).show();
            Log.d(TAG, "FileObserver().onEvent");
        }
    };
    questObserver.startWatching();

    /* create file */
    ObjectOutputStream objectOut = null;
    try {
        FileOutputStream fileOut = context.openFileOutput(fileName, Context.MODE_PRIVATE);
        objectOut = new ObjectOutputStream(fileOut);
        objectOut.writeObject(new Quest());
        fileOut.getFD().sync();
    } catch (IOException e) {
        Log.d(TAG, e.getMessage());
    } finally {
        if (objectOut != null) {
            try {
                objectOut.close();
            } catch (IOException e) {
                Log.d(TAG, e.getMessage());
            }
        }
    }

    /* read file */
    ObjectInputStream objectIn = null;
    Quest quest = null;

     try {
         FileInputStream fileIn = context.openFileInput(fileName);
         objectIn = new ObjectInputStream(fileIn);
         quest = (Quest) objectIn.readObject();
     } catch (FileNotFoundException e) {
         // Do nothing
     } catch (IOException e) {
         e.printStackTrace();
     } catch (ClassNotFoundException e) {
         e.printStackTrace();
     } finally {
         if (objectIn != null) {
             try {
                 objectIn.close();
             } catch (IOException e) {
                 Log.d(TAG, e.getMessage());
             }
         }
     }
     Toast.makeText(context, quest.getTitle(), Toast.LENGTH_LONG).show();

    questObserver.stopWatching();

非常感谢您的帮助。


3
你需要完整的路径,不仅仅是文件名;"quest" - 这是你粘贴代码示例时刚编辑的吗?此外,在开始观察它之前,文件或文件夹需要存在。 - Jens
2个回答

2
"public abstract void onEvent (int event, String path)" - 这个方法在一个特殊的FileObserver线程上被调用。它独立于任何线程运行,因此要注意使用适当的同步!考虑使用post(Runnable)将事件处理工作转移到主线程,以避免并发问题。

http://developer.android.com/reference/android/os/FileObserver.html

如果你通过handler.post(new Runnable(){...})来处理吐司,那应该可以工作。

1
假设您的文件不存在(总是),您应该将观察者放在文件夹上,可以像这样获得:
Context ctx = ...;
File filesFolder = ctx.getFilesDir();

请注意,这也将确保创建filesFolder目录。
现在,只要使用例如Context#.openFileOutput(..)写入、删除或更新文件,您的观察者就会收到通知 - 您可以在FileObserver中过滤文件名,例如您的示例“quest”。

我已经编辑了我的代码,但仍然无法触发onEvent方法。我能够验证我正在写入和读取文件。我认为我没有从filesFolder对象中正确获取路径。但我认为这是正确的。(到目前为止,我对文件的处理很少) - Richard Rhyan
1
这不是 FileObserver 故障 - 你正在尝试在 onEvent 中创建一个 Toast,我注意到了 - 这是行不通的,因为 FileObserver 在单独的线程中运行(而 Toast 应该在 UI 线程上创建)。如果你需要 Toast,你应该创建一个 Handler 并将任何想要显示的信息发布到其中。 - Jens
Toast 只是为了让我看看它是否工作。我已经将其删除并再次尝试,但日志函数仍然没有生效。 - Richard Rhyan
没事了...我试过使用fileFolder.getName()。但是它只适用于fileFolder.getPath()。 非常感谢您的帮助!! - Richard Rhyan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接