【问题标题】:`GeneratePresignedUrl` needs AsyncTask?`GeneratePresignedUrl` 需要 AsyncTask 吗?
【发布时间】:2016-11-09 15:02:54
【问题描述】:

目前在我的 android 项目中,我使用 GeneratePresignedUrlAmazon s3 获取私有文件的链接。在它开始提供NetworkOnMainThreadException 之后,它在主线程上运行良好几次。我的问题是GeneratePresignedUrl 需要Asynctask 吗?或者它是一个错误?

Android Aws sdk 版本 2.2.20(新版)。

代码:来自 Util.java

public static URL getSignedUrl(Context context,String imageString){
    URL url=null;

           try {
               System.out.println("Generating pre-signed URL.");
               java.util.Date expiration = new java.util.Date();
               long milliSeconds = expiration.getTime();
               milliSeconds += 1000 * 60 * 60; // Add 1 hour.
               expiration.setTime(milliSeconds);
                sGenerateSignedUrl = new GeneratePresignedUrlRequest(Constants.BUCKET, imageString);
                sGenerateSignedUrl.setMethod(HttpMethod.GET);
                sGenerateSignedUrl.setExpiration(expiration);
                url = getS3Client(context.getApplicationContext()).generatePresignedUrl(sGenerateSignedUrl);


                System.out.println("Pre-Signed URL = " + url.toString());
               //if(url!=null)
               return url;
           }catch (AmazonServiceException exception) {
                System.out.println("Caught an AmazonServiceException, " +
                        "which means your request made it " +
                        "to Amazon S3, but was rejected with an error response " +
                        "for some reason.");
                System.out.println("Error Message: " + exception.getMessage());
                System.out.println("HTTP  Code: " + exception.getStatusCode());
                System.out.println("AWS Error Code:" + exception.getErrorCode());
                System.out.println("Error Type:    " + exception.getErrorType());
                System.out.println("Request ID:    " + exception.getRequestId());
            } catch (AmazonClientException ace) {
                System.out.println("Caught an AmazonClientException, " +
                        "which means the client encountered " +
                        "an internal error while trying to communicate" +
                        " with S3, " +
                        "such as not being able to access the network.");
                System.out.println("Error Message: " + ace.getMessage());
            }


    return url;
}

像这样调用上面的方法。

URL url = Util.getSignedUrl(getContext().getApplicationContext(),"image path string");

它运行了 20 多次,效果非常好。后来开始举报NetworkOnMainThreadException

【问题讨论】:

  • 我的解决方案是抓住NetworkOnMainThreadException。我从 S3 加载一些图像,所以如果它被抛出,我只是抓住它,什么也不做。你的解决方案是什么?

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


【解决方案1】:

AmazonS3.generatePresignedUrl 本身不发出网络请求。但是,要创建预签名的 Url,它需要来自 AmazonS3 客户端的凭据,并且来自 CognitoCacheingCredentialsProvider 的凭据提供给 STS 和 Cognito 身份服务的网络调用。这就是NetworkOnMainThreadException 的原因。如果凭据是从以前的调用中缓存的,则不会引发此类异常。希望这能解释清楚。

【讨论】:

  • 谢谢。但是上传对象不需要异步任务吗?我的意思是使用带有凭据的 Amzons3 客户端。
  • 任何发出网络请求的东西都必须从后台线程中调用。所以是的,AmazonS3.putObject 需要 AsyncTask(或后台线程)。另一种方法是使用 TransferUtility 来为您解决这个问题。
  • 是的。我只使用 transferutility。
  • 杨帆你是对的,但我们该如何处理呢?我在亚马逊上有图像列表,因此需要添加 asyncTask,这对我的应用程序加载过多。请帮我摆脱这个
【解决方案2】:

您几乎应该始终在线程上或作为异步任务运行网络操作。 为了避免 NetworkOnMainThreadException,在你的类中添加


StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy); 

【讨论】:

  • 我不知道 GeneratePresignedUrl 真的需要 AsyncTask,这就是我发布的原因。如果它需要 Thread 或 Asynctask,我会放在它们周围。但是,将您建议的行跳过 networkeonmainthreadexception.Ok 但它仍然会阻止 Ui 吗?
【解决方案3】:
  • 使用最新的 Aws SDK 版本

  • 在 AmazonS3Client 中使用 credie 传递区域

有趣的生成URL( 对象键:字符串, ACCESS_KEY:字符串, SECRET_KEY:字符串, BUCKET_NAME:字符串 ):网址? {

    val creds = BasicAWSCredentials(ACCESS_KEY ,SECRET_KEY)
    val s3 = AmazonS3Client(
        creds, Region.getRegion(
            Regions.US_EAST_2
        )
    )
    val expires = Date(Date().time + 1000 * 60 * 60)

    val keyFile = objectKey
    val generatePresignedUrlRequest = GeneratePresignedUrlRequest(
       BUCKET_NAME,
        keyFile
    )
    generatePresignedUrlRequest.expiration = expires
    val url: URL = s3.generatePresignedUrl(generatePresignedUrlRequest)

    return url
}

}

【讨论】:

    猜你喜欢
    • 2012-12-12
    • 1970-01-01
    • 1970-01-01
    • 2013-06-23
    • 2020-07-29
    • 2018-11-13
    • 2016-01-29
    • 2019-11-01
    • 1970-01-01
    相关资源
    最近更新 更多