ArrayList Length在Singleton中获得0

时间:2016-05-09 10:42:44

标签: android memory-management singleton

我使用单例从Web服务获取数据并将结果数据对象存储在ArrayList中。它看起来像这样:

public class DataHelper {

private static DataHelper instance = null;

private List<CustomClass> data = null;

protected DataHelper() {
    data = new ArrayList<>();
}

public synchronized static DataHelper getInstance() {
    if(instance == null) {
        instance = new DataHelper();
    }
    return instance;
}

public void fetchData(){

    BackendlessDataQuery query = new BackendlessDataQuery();
    QueryOptions options = new QueryOptions();
    options.setSortBy(Arrays.asList("street"));
    query.setQueryOptions(options);

    CustomClass.findAsync(query, new AsyncCallback<BackendlessCollection<CustomClass>>() {
        @Override
        public void handleResponse(BackendlessCollection<CustomClass> response) {

            int size = response.getCurrentPage().size();

            if (size > 0) {
                addData(response.getData());
                response.nextPage(this);
            } else {
                EventBus.getDefault().post(new FetchedDataEvent(data));
            }

        }

        @Override
        public void handleFault(BackendlessFault fault) {
            EventBus.getDefault().post(new BackendlessFaultEvent(fault));
        }
    });

}

public List<CustomClass> getData(){
    return this.data;
}

public void setData(List<CustomClass> data){
    this.data = data;
}

public void addData(List<Poster> data){
    this.data.addAll(data);
}

public List<CustomClass> getData(FilterEnum filter){

    if(filter == FilterEnum.NOFILTER){
        return getData();
    }else{
        // Filtering and returning filtered data
    }

    return getData();
}
}

正确获取数据,列表实际上包含数据。此外,按预期只创建一个实例。但是,每当我稍后调用getData时,this.data的长度为0.因此,我还尝试使用Application的子类来保存DataHelper对象,从而导致同样的问题。

  1. 有一个很好的调试方法吗?在Android Studio中有类似全局手表吗?
  2. 我的方法有问题吗?有更好的方法吗?我主要是iOS开发人员,所以Android对我来说很新鲜。我在不同的视图中显示ArrayList中的数据,因此只要应用程序运行,我希望它存在于ArrayList中。
  3. 谢谢!

    编辑:在列表视图片段中使用示例(仅限相关部分):

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        filter = FilterEnum.NOFILTER;
        data = DataHelper.getInstance().getData(filter);
    }
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
    customClassListAdapter = new customClassListAdapter(getActivity(), data);}
    

    EDIT2:添加了我从Backendless获取数据的代码,在第一次编辑中将DataHelper的引用更改为数据引用

    EDIT3:我发布了一个本地EventBus,用于通知列表视图有关新数据的信息。这看起来像这样并且有效(最初数据被填充,但是在应用过滤器之后,我用getData得到的ArrayList是空的):

    @Subscribe
    public void onMessageEvent(FetchedDataEvent event) {
        customClassListAdapter.notifyDataSetChanged();
    }
    

3 个答案:

答案 0 :(得分:0)

尝试而不是保持对DataHelper实例的引用,并保持对检索项目列表的引用。 F.E.当你第一次获取列表时(如你所说的那样),将它分配给一个类成员。或者通过它来创建自己的对象数组列表以供将来使用。

答案 1 :(得分:0)

在填充数据之前,可能会调用getData。

调试此方法的一种简单方法是在fetchData,addData和getData中的战略位置添加(导入android.util.LogLog.i("MyApp.MyClass.MyMethod", "I am here now");条目,然后从adb logcat显示的日志中确保数据已填充在getData被调用之前。

答案 2 :(得分:0)

好的,我终于找到了问题。它根本不是关于对象或内存管理。由于我将getData的引用提供给我的ArrayAdapter,每当我在ArrayAdapter上调用clear(我在更改过滤器时都这样做)时,它会清空引用。我基本上必须为ArrayAdapter创建结果的副本:

data = new ArrayList<>(DataHelper.getInstance().getData(filter));

我根本没有意识到这是一个参考。因此,数据总是完全保留在帮助器中。我只这样做是因为:

 customClassListAdapter.notifyDataSetChanged();

在这里做热门帮助,它不再使用新过滤器调用getData。

感谢大家的贡献,你肯定帮我调试了这个。