サーバーに他のデータ (添付ファイル付きの電子メールに非常に似ています) と一緒に画像を取得する必要があります。また、失敗したときに再試行できるように、信頼できる方法で行う必要があります。
サーバーはWCF RESTサーバーであり、私はそれ(JSON)と他の多くの通信を行いますが、画像をアップロードするためのこの新しい要件を取得しました.
JSON を使用してデータをサーバーに投稿するため、Android 側で GSON を使用してデータをシリアル化します。
これまでに実装した方法は次のとおりです(他のすべてはこのように機能しますが、画像から始めたばかりです)
- ユーザー入力アクティビティ フィールド (テキスト データ)
- ユーザーはカメラ インテントを介して写真を撮ります。現在、写真用に1つのファイルを使用しています
- SDカードから写真を撮り、ロード/サイズ変更します-ImageViewに表示し、バイト[]に保存します
- ユーザー送信 - byte[] から画像とともにすべてのデータを取得し、それを Java オブジェクトに入れます
- GSON コンバーターを呼び出してオブジェクトをシリアル化する
- オブジェクトを SQLite に保存する
- AsyncTask は SQLite でレコードを検索し、カーソルを開き、テキストを取得します
- AsyncTask は HttpConnection を作成し、テキスト データをサーバーに投稿します。
- 終わり
今私の問題に..明らかに#3で-バイト配列でRAMを「爆発」させます。時々、Nexus S の動作が遅くなったとさえ感じます。しかし、そうすることで、SDカードやアプリフォルダーが多くのファイルでいっぱいになることを避けています。私は写真を撮り、それをつかみます。次の画像は前の画像を上書きします。
ステップ 5 は遅いです。私は GSON でカスタムシリアライザーを試していませんでした。バイト配列を [1,-100,123,-12] のようなものにシリアライズする代わりに、Base64 ではるかに小さいサイズを取得できますが、それでも. 遅くなります。しかも20枚まで撮れる…
手順 6 は問題ありません。しかし、特定のサイズ(300pxの画像を試しました)で、OpenCursorのステップ7でエラーが発生し始めました
07-06 20:28:47.113: ERROR/CursorWindow(16292): need to grow: mSize = 1048576, size = 925630, freeSpace() = 402958, numRows = 2
07-06 20:28:47.113: ERROR/CursorWindow(16292): not growing since there are already 2 row(s), max size 1048576
07-06 20:28:47.113: ERROR/Cursor(16292): Failed allocating 925630 bytes for text/blob at 1,1
だから、この全体は私が好きなものではありません。理想的には、すべてのデータを 1 つにまとめてサーバーにアップロードする必要があります。
タイムスタンプ付きの画像をSDカードに保存し、その名前だけをDBに保存することを考えていました。サーバーに送信する直前にそれらを処理するよりも。成功したら、それらの画像を削除します。この種のロジックは SQLite スキーマをより複雑にしますが、これ以上の方法はないのではないでしょうか?!
画像を処理するためのベストプラクティスを探していると思います。最小限のメモリ/CPU 使用率でフォローインを行う方法:
- 写真を撮る
- サムネイル表示
- サイズ変更
- サーバーに送信
編集1:
現在、シザン全体をマルチパート MIME メッセージとしてアップロードする可能性を調査しています。それには、私の Android パッケージにいくつかの JAR を追加する必要があります。また、画像をロードして送信するためのApacheコードがどれほど効果的かはわかりません(私のコードよりも優れていると思います) http://okandroidletsgo.wordpress.com/2011/05/30/android-to-wcf-streaming-マルチパートバイナリイメージ/
そして、組み込みの.NETフレームワークではこれを行う方法がないため、WCF側でこれらすべてを解析する必要があります。
http://antscode.blogspot.com/2009/11/parsing-multipart-form-data-in-wcf.html
これを試したら教えてください!
編集2:
MIME はダメです。同じものであるBase64を使用してバイナリをシリアル化するため、意味がありません..