簡體   English   中英

Robospice存儲對象,通過Ormlite在數據庫中擴展ArrayList

[英]Robospice storing object that extends ArrayList in database via Ormlite

背景

我一直在嘗試修改Robospice Ormlite示例代碼 ,我已成功運行該代碼 我所做的唯一更改是我有一個包含對象數組的JSON響應。

我創建了2個類:

public class Foos extends ArrayList<Foo>
public class Foo

我遇到了初始問題,因為我的JSON響應是一個沒有外部容器的純數組。 我通過谷歌小組了解到解決這個問題的方法是創建一個擴展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中觸及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();

        }
    }

我試過了什么

我試圖用Ormlite注釋來注釋類Foo,看看這個庫是否需要幫助,但仍然沒有運氣。 如下所述:

@DatabaseTable
public class Foo {

    @DatabaseField(generatedId = true)
    private int id;

    @DatabaseField
    private String someText;

}

當我真的想要一個存儲Foo的數據庫表時,我想知道這是否是Foos類的結果。 任何建議都會很棒!

這個問題實際上並不是RoboSpice中的錯誤,而是ORM Lite模型的限制。

如果要使用ORMLite序列化Foo集合,則必須使用序列化作為Foo集合的類。 你接近是對的。 然而,你不能只是擺脫它來單獨存儲Foo元素。 您不僅需要使用Foos類來解析響應,還需要將數據存儲在數據庫中。

Foos應該:

  • 定義一個id
  • 使用DataBaseTable和DataField以及Foreign集合進行注釋

問題是你不能注釋一個類並說“我是一個Foreig集合”。 此注釋只能用於字段,而不能用於類。 因此,如果你的班級將“持有”一個集合,那將是有效的,但不適用於“是一個”集合的類。

所以,我認為簡短的回答是:不,你不能用ORM Lite做到這一點。 你必須存儲像Foos這樣的頂級類,但它應該是ORM Lite的可序列化的,為此它需要有一個集合字段,而不能直接收集。

為了補充這個優秀的問題,我也遇到了這種“沉默的失敗”,並且不知道該怎么做。 我最終在Android工作室內選擇了查看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;

正如@Snicolas所說,你應該改為Collection而不是ArrayList。 我想做或多或少相同但沒有結果對象,我在這個問題上的解決方法RoboSpice堅持使用OrmLite的JSON數組應該適合你。

@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
    ...
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM