如果我先调用AmazonS3Client.listObjects,则AmazonS3Client.putObject不起作用

时间:2013-04-18 12:49:10

标签: java android amazon-web-services amazon-s3

我一直在努力解决这个问题,但没有成功。我正在使用AWS Android SDK将文件上传到AWS S3,有时我的文件会上传到服务器,有些则不会。执行putObject指令,但它只是“挂起”并锁定该行上的代码执行。

通过尝试对代码片段进行注释以找到问题的根源,我得出结论,因为我在上传之前调用了listObjects。

我无法删除此listObjects,因为我需要在App启动时获取文件名,并且只有在用户选择了要上传的内容后才会进行任何上传。

我通常从我的手机上传照片,大约1到1.3 MB,并在不到30秒的时间内完成上传。如果我调用listObjects它会“挂起”。为什么会这样?有没有人知道发生了什么?这里有几行代码:

在android onCreate期间:

weather_data = new ArrayList<Weather>();        
ObjectListing objectListing = s3Client.listObjects(new ListObjectsRequest().withBucketName(lista_de_baldes.get(0).getName()).withPrefix("Thumbs"));
for (S3ObjectSummary objectSummary : objectListing.getObjectSummaries())
    weather_data.add(new Weather(R.drawable.jogo, objectSummary.getKey().replace("Thumbs/", "")));

用户选择要上传的照片后(在扩展AsyncTask以防止主线程冻结的类中,在doInBackground期间执行):

File arquivo = new java.io.File(filePath);
PutObjectRequest por = new PutObjectRequest(
    lista_de_baldes.get(0).getName(),
    filePath.substring(filePath.lastIndexOf('/') + 1),
    arquivo
);
s3Client.putObject(por);

他们使用相同的桶,相同的区域和相同的区域。 objectListing也运行良好。


编辑:我通过在上传代码中再次设置AmazonS3Client变量来“解决”问题。像这样:

s3Client = new AmazonS3Client(
           new BasicAWSCredentials(Constants.ACCESS_KEY_ID, Constants.SECRET_KEY)
       );
s3Client.setRegion(Region.getRegion(Regions.SA_EAST_1));

但这对我没有意义,因为它是一个全局变量。在下载对象列表后,看起来简单得到了“锁定”。任何人都知道发生了什么事?


编辑:根据要求,这里有更多的代码。

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    s3Client = new AmazonS3Client(
                   new BasicAWSCredentials(Constants.ACCESS_KEY_ID, Constants.SECRET_KEY)
                   );
    //mudei de US_WEST_2 para SA_EAST_1 (south america) para acessar um bucket criado em SP/Brazil
    s3Client.setRegion(Region.getRegion(Regions.SA_EAST_1));

    lista_de_baldes = s3Client.listBuckets();

    setContentView(R.layout.main);

    weather_data = new ArrayList<Weather>();        
    ObjectListing objectListing = s3Client.listObjects(new ListObjectsRequest().withBucketName(lista_de_baldes.get(0).getName()).withPrefix("Thumbs"));
    for (S3ObjectSummary objectSummary : objectListing.getObjectSummaries()) {
        File arquivo_thumb = new File(getCacheDir() + File.separator + objectSummary.getKey().replace("Thumbs/", ""));
        weather_data.add(new Weather(R.drawable.jogo, arquivo_thumb.getName().replace(".png", ".jpg")));

        if(arquivo_thumb.exists())
            continue;

        InputStream input = null;
        try {
            ResponseHeaderOverrides override = new ResponseHeaderOverrides();
            override.setContentType("image/jpeg");
            GeneratePresignedUrlRequest urlRequest = new GeneratePresignedUrlRequest(
                    lista_de_baldes.get(0).getName(),
                    "Thumbs/" + arquivo_thumb.getName()
                    );
            urlRequest.setResponseHeaders(override);
            URL url = s3Client.generatePresignedUrl(urlRequest);
                            ...
         }

上传部分:

     protected S3TaskResult doInBackground(Uri... uris) {

        if (uris == null || uris.length != 1) {
            return null;
        }

        // The file location of the image selected.
        Uri selectedImage = uris[0];

        String[] filePathColumn = { MediaStore.Images.Media.DATA };

        Cursor cursor = getContentResolver().query(selectedImage,
                filePathColumn, null, null, null);
        cursor.moveToFirst();

        int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
        filePath = cursor.getString(columnIndex);
        cursor.close();

        S3TaskResult result = new S3TaskResult();

        // Put the image data into S3.
        try {                   
            // Content type is determined by file extension.
            File arquivo = new java.io.File(filePath);
            PutObjectRequest por = new PutObjectRequest(
                    lista_de_baldes.get(0).getName(),
                    filePath.substring(filePath.lastIndexOf('/') + 1),
                    arquivo
                    );
            por.setCannedAcl(CannedAccessControlList.PublicRead);
            s3Client.putObject(por);

1 个答案:

答案 0 :(得分:0)

listObjects是否包含在AsyncTask中?你等到listObjects完成了吗?仅供参考,自Honeycomb 11级以来,默认情况下会顺序执行多个AsyncTask实例。