4

背景

我一直在尝试修改已成功运行的Robospice Ormlite 示例代码。我所做的唯一更改是我有一个包含对象数组的 JSON 响应。

我创建了 2 个类:

public class Foos extends ArrayList<Foo>
public class Foo

我遇到了最初的问题,因为我的 JSON 响应是一个没有外部容器的纯数组。我通过 google groups 了解到,解决这个问题的方法是创建一个扩展 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;
    }

}

问题

代码在没有任何强制关闭的情况下运行,但是我从来没有在我的活动中点击 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 类的结果。任何建议都会很棒!

4

3 回答 3

2

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

如果要使用 ORMLite 序列化 Foo 的集合,则必须使用序列化作为 Foo 集合的类。你的做法是对的。然而,您不能仅仅摆脱它来单独存储 Foo 元素。您不仅要使用 Foos 类来解析响应,还要在数据库中存储数据。

Foos 应该:

  • 定义一个id
  • 使用 DataBaseTable 和 DataField 和 Foreign 集合进行注释

问题是你不能注释一个类并说“I am a Foreig Collection”。这个注解只能用在字段上,不能用在类上。因此,如果您的班级将“持有”一个集合,那将起作用,但不适用于“是”集合的班级。

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

于 2013-04-07T06:42:22.417 回答
2

为了补充这个很好的问题,我也经历了这种“无声的失败”,不知道该怎么办。我最终选择在 Android Studios 中查看 logcat 中的所有消息,因此不仅是 android 错误,还有所有内容。我通过选择“详细”和“无过滤器”来做到这一点。

日志猫

当我运行我的应用程序时,我发现我收到一个静默错误的原因是因为我没有为我的 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;
于 2015-06-13T18:02:55.383 回答
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
    ...
}
于 2013-04-08T11:07:36.013 回答