1
  1. 我有一个 ListActivity 让用户选择要上传的照片
  2. 对于上传,我会将照片放在一个名为 PhotoList 的静态 ArrayList 中
  3. 之后,我将启动一个服务来上传这些照片
  4. 现在,用户可以切换到另一个活动来做一些其他事情
  5. 稍后,用户将返回此 ListActivity 以检查上传状态。同样在这里,他们可以选择要上传的更多照片。

所以,我的PhotoList其实是一种Queue,同时也是ListActivity中要显示的数据。

我的问题是,当服务运行时,用户选择了更多照片,我想把这些照片放在 PhotoList 中。(我不想再次启动服务,因为服务已经在运行......)

现在我只是被困在这里。

4

4 回答 4

3

好的,我会根据我对您的问题的理解尝试为您提供解决方案:您有一个包含照片的列表,并且您希望用户有资格上传这些图像并将其更新为用户状态(已上传/上传/上传/失败)并且您不想在Service每次上传时都开始。

一个简单的工作解决方案是使用IntnetServicei 只有在分配了任务时才会运行,并且在完成工作时自动关闭,当然在使用时工作将在一个单独的线程中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,在循环中,您将研究 this BlockingQueue。两种情况是可能的:

  1. 有一些照片。拿走并上传。
  2. 队列为空。所以线程将进入睡眠状态,BlockingQueue确保这一点。
于 2013-01-06T10:40:31.870 回答
1

您的服务应覆盖 onResume() 函数。每当用户执行其他任务、打开其他活动等并最终返回到应用程序的活动时,都会调用 onResume()。这只是要点。

您可以了解有关运行时更改的更多信息。适用于 Activity 的概念也适用于 Service,因为该 Service 只是没有“显示”给用户。

在上面的链接中,您将了解何时重新创建活动,以及通过调用 onResume() 实际恢复活动的时间。您还需要覆盖onSaveInstanceState()onRestoreInstanceState()以便在旧 Activity 实例和新实例之间传递状态对象。

你可以做的是,当用户离开你的活动时onSaveInstanceState(),你应该保存你的状态变量,例如。您选择的照片列表,在一个 Bundle 中。并将这个 Bundle 传递给onRestoreInstanceState()

问题:您实际上是否将服务作为有效服务启动?我的意思是,你在扩展服务类吗?我已经在我的项目中使用了服务,并且他们总是从他们离开的地方恢复而不覆盖任何东西。原因:服务在后台运行,在服务完成工作之前不会释放资源。因此,如果您还没有使用过 Service ,那么我建议您这样做。您的问题将得到解决。

于 2013-01-06T10:46:38.480 回答
0

你可以使用这个:

写入数组列表时复制

这将是一个线程安全的随机访问列表

检查此链接以获得良好的解释和示例。

ArrayList 和 CopyOnWriteArrayList 的区别

Iterators这个列表永远不会抛出ConcurrentModificationException。创建an 时iterator,它会保留列表内容的副本。迭代这个列表总是安全的

于 2013-01-06T10:49:49.840 回答