4

バックグラウンド

私はRobospice Ormlite のサンプル コードを変更しようとしており、実行に成功しています。私が行った唯一の変更は、オブジェクトの配列を含む JSON 応答があることです。

私は2つのクラスを作成しました:

public class Foos extends ArrayList<Foo>
public class Foo

私の JSON 応答は外部コンテナーのない純粋な配列であるため、初期の問題がありました。これを解決する方法は、ArrayListを拡張する「偽の」クラス(Foos)を作成することであるとGoogleグループを介して読みました。これにより、次のコードが生成されました。

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 コレクションを使用して注釈を付ける

問題は、クラスに注釈を付けて「私は外国のコレクションです」と言うことができないことです。この注釈は、クラスではなくフィールドでのみ使用できます。したがって、クラスがコレクションを「保持」する場合、それは機能しますが、「コレクションである」クラスでは機能しません。

したがって、短い答えは次のとおりだと思います。いいえ、ORM Liteではそれを行うことはできません。Foos のようなトップ クラスを格納する必要がありますが、ORM Lite ではシリアライズ可能である必要があり、そのためにはコレクション フィールドが必要であり、直接コレクションにすることはできません。

于 2013-04-07T06:42:22.417 に答える
1

@Snicolas が言ったように、ArrayList ではなく Collection に変更する必要があります。多かれ少なかれ同じことをしたかったのですが、結果オブジェクトがなければ、この質問に対する私の回避策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
    ...
}
于 2013-04-08T11:07:36.013 に答える