1
  1. ユーザーがアップロードする写真を選択できるようにする ListActivity があります
  2. アップロード用に、PhotoList という静的な ArrayList 内に写真を配置します。
  3. その後、それらの写真をアップロードするサービスを開始します
  4. 現在、ユーザーは別のアクティビティに切り替えて、他のことを行うことができます
  5. 後で、ユーザーはこの ListActivity に戻ってアップロード ステータスを確認します。また、ここで、アップロードする写真をさらに選択することもできます。

つまり、私の PhotoList は実際には一種の Queue ですが、ListActivity で表示されるデータでもあります。

私の問題は、サービスが実行されていて、ユーザーがさらに写真を選んだときに、それらの写真を PhotoList 内に入れたいということです。(サービスはすでに実行されているため、サービスを再度開始したくありません...)

今、私はここで立ち往生しています。

4

4 に答える 4

3

わかりました、あなたの問題に対する私の理解に基づいて解決策を提供しようとします: あなたは写真付きのリストを持っていて、ユーザーがそれらの画像をアップロードし、そのステータスをユーザーに更新する資格があることを望んでいます (アップロード済み/アップロード中/アップロード/失敗)、Serviceアップロードするたびに を開始したくない場合。

簡単な実用的な解決策は、IntnetServiceタスクが割り当てられている場合にのみ実行され、作業が終了すると自動的にシャットダウンされ、もちろん、作業中はジョブが別のスレッドになります。IntentService

step 1

画像に関するデータを含むデータベース テーブルを作成する

_id integer 
_image_uri 
_image_status :  

_image_statusこれらの値のいずれかを保持します (1-uploaded: finish_uploaded、2-uploading: サービスが画像をアップロード中、3-upload: ユーザーが画像をアップロードできます、4-failed: アップロードに失敗しました、再試行できます)

step2

画像をサーバーにアップロードしようとしておりUploadIntentService、アップロードが正常に完了した場合、またはアップロード中にエラーが発生した場合は、データベースを更新します

public class UploadIntentService extends IntentService {
    private static final String TAG = UploadIntentService.class.getSimpleName();
    private static final int STATUS_UPLOAD = 0x01; //can be uploaded
    public static final int STATUS_FAILED_TO_UPLOAD = 0x02; // tried to upload but failed
    public static final int STATUS_UPLOADING = 0x03; // self explanied
    public static final int STATUS_SUCCESSFULLY_UPLOADED = 0x04; // the image uploaded to server 

    public UploadIntentService() {
        super(TAG);

    }

    @Override
    protected void onHandleIntent(Intent intent) {

        int status = intent.getIntExtra("status", -1);
        String imageUri = intent.getStringExtra("image_path");
        long imageDatabaseid = intent.getLongExtra("image_db_address",-1);

        if(status != STATUS_SUCCESSFULLY_UPLOADED && status != STATUS_UPLOADING){

            try{
                //update _image_status column with value of STATUS_UPLOADING with the image_id = imageDatabaseid;

                //upload code 

                //successfully uploaded 
                //update _image_status column with value of STATUS_SUCCESSFULLY_UPLOADED with the image_id = imageDatabaseid;
            }catch(Exception ex){
                ex.printStackTrace();
                //update _image_status column with value of STATUS_FAILED_TO_UPLOAD with the image_id = imageDatabaseid;
            }
        }

    }

}

……

step3

画像をアップロードするListActivity場合は、このコードを使用します

Intent intent = new Intent(context, UploadIntentService.class);
    Bundle uploadExtras = new Bundle(3);
    uploadExtras.putLong("image_db_address", PUT HERE THE IMAGE DATABASE ID );
    uploadExtras.putInt("status", PUT HERE THE IMAGE STATUS );
    uploadExtras.putString("image_path", PUT HERE THE IMAGE PATH IN FILE SYSTEM);

    intent.putExtras(uploadExtras);
    context.startService(intent);

....... 手順 4

manifest.xml でサービスを宣言していることを確認してください。

于 2013-01-06T10:53:30.367 に答える
1

BlockingQueueアップロードする写真を保存する を作成できます。これBlockingQueueはあなたのPhotoList. のループで、これServiceを調べますBlockingQueue。次の 2 つのケースが考えられます。

  1. 一部写真あり。それを取ってアップロードします。
  2. キューが空です。したがって、スレッドはスリープ状態になり、BlockingQueueこれが保証されます。
于 2013-01-06T10:40:31.870 に答える
1

サービスは onResume() 関数をオーバーライドする必要があります。onResume() は、ユーザーが他のタスクを実行したり、他のアクティビティを開いたりするたびに呼び出され、最終的にアプリケーションのアクティビティに戻ります。それは要点です。

ランタイムの変更点について詳しく知ることができます。アクティビティに適用される概念は、サービスにも適用されます。つまり、サービスはユーザーに「表示」されません。

上記のリンクでは、アクティビティが再作成されるタイミングと、onResume() を呼び出して実際に再開されるタイミングを学習します。また、古い Activity インスタンスと新しい Activity インスタンスの間で状態オブジェクトを渡すために、onSaveInstanceState()andをオーバーライドする必要があります。onRestoreInstanceState()

あなたができることは、ユーザーがアクティビティを離れたときに、onSaveInstanceState()状態変数を保存する必要があることです。バンドル内の選択した写真のリスト。そして、このバンドルをに渡しますonRestoreInstanceState()

質問:実際にサービスを有効なサービスとして開始していますか? つまり、 Service クラスを拡張していますか? 私は自分のプロジェクトに Service を使用してきましたが、それらは常に何もオーバーライドせずに元の場所から再開しました。理由:サービスはバックグラウンドで実行され、リソースはサービスの実行が完了するまで解放されません。したがって、 Service を使用していない場合は、使用することをお勧めします。あなたの問題は世話をされます。

于 2013-01-06T10:46:38.480 に答える
0

これを使用できます:

コピー オン ライト配列リスト

これは、スレッドセーフなランダム アクセス リストになります。

適切な説明と例については、このリンクを確認してください。

ArrayList と CopyOnWriteArrayList の違い

Iteratorsこのリストの は決してスローしませんConcurrentModificationException。が作成されるiteratorと、リストの内容のコピーが保持されます。このリストを繰り返しても安全です。

于 2013-01-06T10:49:49.840 に答える