2013-04-04 91 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;