【问题标题】:ContentObserver onChange() method gets called many timesContentObserver onChange() 方法被多次调用
【发布时间】:2014-02-25 11:05:07
【问题描述】:

我需要跟踪在设备上创建的任何 .jpg 类型的新图像文件。 我已经在MediaStore 上使用ContentObserver 使用下面的类MediaStoreObserver 完成了这项工作,并且, 在我的一项服务中注册相同的内容。

我注意到onChange() 方法被多次调用以创建单个文件。 我知道创建的媒体文件会在MediaStore 的许多表中更新,因此onChange() 会被多次调用。

我的问题:如何注册到MediaStore 仅用于图像文件创建/编辑操作?

-提前致谢, 馒头

    private class MediaStoreObserver extends ContentObserver {
    public MediaStoreObserver() {
        super(null);
    }

    @Override
    public void onChange(boolean selfChange) {
        super.onChange(selfChange);

        //check image file changes in MediaStore
        readFromMediaStore(_context,MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
    }
}

//register for external media changes for image files
if(mediaStoreObserver!=null){
  _context.getContentResolver().registerContentObserver(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
        false,mediaStoreObserver);

【问题讨论】:

  • 你在哪里注销了这个观察者??如果你没有检查你的代码是否多次注册了这个观察者。
  • 这是在服务 onCreate() 中注册的,同样会在我的服务的 onDestroy() 中取消注册。

标签: android contentobserver


【解决方案1】:

简短回答:你不能,它是提供者发送notifyChange(与观察者onChange一起接收),只要有:更新/插入/删除

更长的答案:这是实现您想要的(如何注册到 MediaStore 仅用于图像文件创建/编辑操作?):

在启动时从 MediaStore 读取图像表,并将 _data 列(文件路径)存储在已排序的 collection 和带有路径(字符串)的已排序 collection 中。每当您收到onChange 调用时,请创建一个上述排序的新集合,然后循环遍历新集合并使用二分搜索搜索您创建的原始集合(因为集合已排序,我们希望保持较低的时间复杂度)。这将导致运行时间为 O(n*logn) 的非常有效的实现。

或者在伪代码中:

1. Read current image columns from media store (the `_data column as projection)
2. Store result in a collection, with string type
3. Sort collection
4. Upon `onChange` is received, make a new collection as step 1-3
5. Loop over collection created in 4 and search each string you take out with 
binary search in the sorted collection you got from step 3, if item is not found 
then the item is new
6. Make the collection in 4 the current cached version of mediastore 
7. Time complexity is O(n*log n) for the above algorithm 

编辑对于更新的文件部分,每当我在第 5 步中的搜索命中时,我都会从 MediaStore 读取日期修改字段,这意味着您实际上应该存储文件 (uri) 和在数据类中修改日期,但作为搜索查找使用文件路径。每当找到文件时,您应该检查修改日期是否匹配,如果不匹配,则它是一个更新的文件。

【讨论】:

    【解决方案2】:

    我遇到了同样的问题,并通过从我的 onchange 覆盖中删除 super.onchange 来解决它。

    【讨论】:

    • 这对我不起作用。执行此操作时会收到 ANR。
    猜你喜欢
    • 2018-01-01
    • 2012-02-25
    • 2011-11-21
    • 1970-01-01
    • 2011-08-26
    • 2014-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多