2013-04-04 51 views
4

背景Robospice存储对象,通过Ormlite扩展数据库中的ArrayList

我一直在试图修改Robospice Ormlite example code,我已经成功运行。我所做的唯一更改是我有一个包含对象数组的JSON响应。

我创建2类:

public class Foos extends ArrayList<Foo> 
public class Foo 

我有最初的问题,因为我的JSON响应是一个纯粹的阵列没有外容器。我通过google群体阅读,解决这个问题的方法是创建一个扩展ArrayList的“假”类(Foos)。这产生了下面的代码:

public class FooRequest extends SpringAndroidSpiceRequest<Foos> { 

    private String baseUrl; 

    public FooRequest() { 
     super(Foos.class); 
     this.baseUrl = "http://somewhere.com/jsonurl"; 
    } 

    @Override 
    public Foos loadDataFromNetwork() throws RestClientException { 
     Ln.d("Call web service " + baseUrl); 
     return getRestTemplate().getForObject(baseUrl, Foos.class); 
    } 
} 

然后我创建了以下服务代码,从这些例子改编而来。

public class MySpiceService extends SpringAndroidSpiceService { 

    private static final int WEBSERVICES_TIMEOUT = 10000; 

    @Override 
    public CacheManager createCacheManager(Application application) { 
     CacheManager cacheManager = new CacheManager(); 
     List< Class<?>> classCollection = new ArrayList< Class<?>>(); 

     // add persisted classes to class collection 
     classCollection.add(Foos.class); 

     // init 
     RoboSpiceDatabaseHelper databaseHelper = new RoboSpiceDatabaseHelper(application, "sample_database.db", 2); 
     InDatabaseObjectPersisterFactory inDatabaseObjectPersisterFactory = new InDatabaseObjectPersisterFactory(application, databaseHelper, classCollection); 
     cacheManager.addPersister(inDatabaseObjectPersisterFactory); 
     return cacheManager; 
    } 

    @Override 
    public RestTemplate createRestTemplate() { 
     RestTemplate restTemplate = new RestTemplate(); 
     // set timeout for requests 

     HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory(); 
     httpRequestFactory.setReadTimeout(WEBSERVICES_TIMEOUT); 
     httpRequestFactory.setConnectTimeout(WEBSERVICES_TIMEOUT); 
     restTemplate.setRequestFactory(httpRequestFactory); 

     // web services support xml responses 
     MappingJacksonHttpMessageConverter jsonConverter = new MappingJacksonHttpMessageConverter(); 
     FormHttpMessageConverter formHttpMessageConverter = new FormHttpMessageConverter(); 
     StringHttpMessageConverter stringHttpMessageConverter = new StringHttpMessageConverter(); 
     final List< HttpMessageConverter<?>> listHttpMessageConverters = restTemplate.getMessageConverters(); 

     listHttpMessageConverters.add(jsonConverter); 
     listHttpMessageConverters.add(formHttpMessageConverter); 
     listHttpMessageConverters.add(stringHttpMessageConverter); 
     restTemplate.setMessageConverters(listHttpMessageConverters); 
     return restTemplate; 
    } 

} 

问题

代码运行但没有任何力量关闭我从来不打我activity.Neither内RequestListener内部类的成功或失败消息的方法被解雇,它似乎相当困难调试,所以它感觉像一个“无声失败”。

public final class MyRequestListener implements RequestListener<Foos> { 

     @Override 
     public void onRequestFailure(SpiceException spiceException) { 
      Toast.makeText(SampleSpiceActivity.this, "failure", Toast.LENGTH_SHORT).show(); 
     } 

     @Override 
     public void onRequestSuccess(final Articles result) { 
      Toast.makeText(SampleSpiceActivity.this, "success", Toast.LENGTH_SHORT).show(); 

     } 
    } 

我已经试过

我曾尝试注释类Foo,与Ormlite注释,看是否所需的函数库了援助之手,但仍没有运气。如下所示:

@DatabaseTable 
public class Foo { 

    @DatabaseField(generatedId = true) 
    private int id; 

    @DatabaseField 
    private String someText; 

} 

我不知道这是否是Foos类的结果,当我真的想要一个存储Foo的数据库表时。任何建议都会很棒!

+0

RoboSpice附带调试启用日志记录,是logcat的打印有用的东西? – rciovati 2013-04-04 07:48:27

+0

我一直试着用不同的断点,但logcat中没有什么有趣的东西出现。正如你在代码中看到的那样,我也保存了一些调试信息。 – 2013-04-04 08:56:18

+0

在没有任何回答的情况下在这里找到同样的问题https://groups.google.com/forum/?fromgroups=#!searchin/robospice/ormlite/robospice/inqSyQkwGn8/axXhozO7PTIJ – 2013-04-04 15:04:52

回答

2

这个问题不是RoboSpice中的一个错误,而是ORM Lite模型的一个限制。

如果你想使用ORMLite序列化一个Foo集合,那么你必须使用序列化一个Foo集合的类。你的方法是对的。尽管如此,你不能只是摆脱它来单独存储Foo元素。您不仅必须使用Foos类来解析响应,还需要将数据存储在数据库中。

FOOS应该:

  • 定义ID
  • 使用DataBaseTable和数据字段和国外收集

的问题是,你不能标注类,并说被标注为“我是一个外国收藏“。此批注只能用于字段,而不能用于类。所以,如果你的班级“拥有”一个集合,那将起作用,但不适用于“是”集合的班级。

所以,我相信简短的回答是:不,你不能用ORM Lite做到这一点。你必须存储一个像Foos这样的顶级类,但它应该是ORM Lite的序列化类,因此它需要有一个集合字段,并且不能直接作为集合。

1

正如@Snicolas所说,你应该改为Collection而不是ArrayList。我想做的或多或少相同,但没有结果对象,我在这个问题上的解决方法RoboSpice persist JSON array with OrmLite应该为你工作。

@DatabaseTable 
public class Foos { 
    @DatabaseField(id = true) 
    private int id; 
    @ForeignCollectionField(eager = false) 
    private Collection<Foo> result; 

    // getters and setters 
    ... 
} 

@DatabaseTable 
public class Foo { 
    @DatabaseField(id = true) 
    private int id; 
    @DatabaseField(foreign = true) 
    private Foos foos; 

    // getters and setters 
    ... 
} 
2

为了增加这个优秀的问题,我也遇到了这个'沉默失败',不知道该怎么做。 我最终选择在Android Studios内部查看logcat中的所有消息,因此不仅是android错误,还包括所有内容。我通过选择“详细”和“无过滤器”来实现这一点。

logcat

当我跑我的应用程序,我发现,为什么我得到一个无声的错误的原因是因为我没有为我的SQL生成唯一的ID,这导致它弹了出来。

Caused by: android.database.sqlite.SQLiteConstraintException: UNIQUE constraint failed: post.ID (code 1555) 

我固定它通过对我的外部类ID字段这使得它本身产生的唯一ID这样做:

@DatabaseField(allowGeneratedIdInsert=true, generatedId=true) 
private int ID;