title: Android AWS S3 SDK TransferUtility Not Working in Service
body: <p>I am trying to use the AWS Android SDK for S3 in a started service. I am a little new to both the SDK and Services. I am pretty confident that the Transfer Utility is also running a service.</p>
  
  <pre><code>Handler (android.os.Handler) {11629d87} sending message to a Handler on a dead thread
      java.lang.IllegalStateException: Handler (android.os.Handler) {11629d87} sending message to a Handler on a dead thread
      at android.os.MessageQueue.enqueueMessage(MessageQueue.java:325)
      at android.os.Handler.enqueueMessage(Handler.java:631)
      at android.os.Handler.sendMessageAtTime(Handler.java:600)
      at android.os.Handler.sendMessageDelayed(Handler.java:570)
      at sksDoneLater(TransferService.java:189)
      at com.amazonaws.mobileconnectors.s3.transferutility.TransferService.access$200(TransferService.java:44)
      at com.amazonaws.mobileconnectors.s3.transferutility.TransferService$2.handleMessage(TransferService.java:166)
      at android.os.Handler.dispatchMessage(Handler.java:98)
      at android.os.Looper.loop(Looper.java:135)
      at android.os.HandlerThread.run(HandlerThread.java:61)
  </code></pre>
  
  <p>Here is the code I am using to start it up:</p>
  
  <pre><code>    AmazonS3 amazonS3 = new AmazonS3Client(credentialsProvider);
      mTransferUtility = new TransferUtility(amazonS3, getApplicationContext());
      TransferObserver observer = mTransferUtility.upload(
              S3_RAW_BUCKET_ARN,
              mVidFileKey,
              mVidFile);
  
      observer.setTransferListener(new TransferListener() {...})
  </code></pre>
  
  <p>The line previous it says it can't get s3 client. I created the client just as shown above in application class and successfully used the same code in an activity to perform a successful transfer so it must be something obvious about services that I am ignorant of. The above code is called in a method that is called from <code>onStartCommand()</code> in the service.</p>
  
  <p>Any help would be much appreciated.</p>
  
  <p>UPDATE - Whole Class was requested and is shown here:</p>
  
  <pre><code>public class VideoCompressionService extends Service {;
  
  private Bus bus;
  private TransferUtility mTransferUtility;
  private int mVidWidth;
  private int mVidHeight;
  private File mCompressedVidFile;
  private File mVidFile;
  private String mVidFileKey;
  private NotificationManager mNotificationManager;
  private android.support.v4.app.NotificationCompat.Builder mNotification;
  
  public VideoCompressionService() {
  
  }
  
  @Override
  public int onStartCommand(Intent intent, int flags, int startId) {
      if (intent != null) {
          String realPath = MediaUtils.getRealVideoPathFromURI(this.getContentResolver(), intent.getData());
          if (realPath != null) {
              this.mVidFile = new File(realPath);
              this.mVidFileKey = intent.getStringExtra(EXTRA_VID_FILE_KEY);
              this.mVidWidth = intent.getIntExtra(EXTRA_VID_WIDTH, 0);
              this.mVidHeight = intent.getIntExtra(EXTRA_VID_HEIGHT, 0);
              this.bus = CoPhotoApplication.getVideoCompressionBus();
              if (mVidFile != null &amp;&amp; mVidFile.exists() &amp;&amp; mVidFile.canRead()) {
                  mNotificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
                  mNotification = new NotificationCompat.Builder(this)
                          .setContentTitle("Compressing Video - Step 1 of 3")
                          .setContentText("Uploading video for processing...")
                          .setSmallIcon(R.drawable.ic_launcher);
                  if (mVidWidth == 0 || mVidHeight == 0) {
                      MediaMetadataRetriever mmr = new MediaMetadataRetriever();
                      mmr.setDataSource(mVidFile.getAbsolutePath());
                      mVidWidth = Integer.parseInt(mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH));
                      mVidHeight = Integer.parseInt(mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT));
                      mmr.release();
                  }
                  uploadVidToS3();
              }
              return Service.START_NOT_STICKY;
          } else {
              VideoCompressionService.this.stopSelf();
              return Service.START_NOT_STICKY;
          }
      } else {
          VideoCompressionService.this.stopSelf();
          return Service.START_NOT_STICKY;
      }
  }
  
  @Nullable
  @Override
  public IBinder onBind(Intent intent) {
      return null;
  }
  
  private void uploadVidToS3() {
      compressionUploadStarted();
      CognitoCachingCredentialsProvider credentialsProvider = new CognitoCachingCredentialsProvider(
              getApplicationContext(),
              "*********ID HERE********", // Identity Pool ID
              Regions.US_EAST_1 // Region
      );
  
      AmazonS3 amazonS3 = new AmazonS3Client(credentialsProvider);
      mTransferUtility = new TransferUtility(amazonS3, getApplicationContext());
      TransferObserver observer = mTransferUtility.upload(
              S3_RAW_BUCKET_ARN,
              mVidFileKey,
              mVidFile);
  
      observer.setTransferListener(new TransferListener() {
          @Override
          public void onStateChanged(int id, TransferState state) {
              if (state == TransferState.COMPLETED) {
                  compressionUploadFinished(true);
                  zencodeVideo(mVidFileKey);
              } else if (state == TransferState.FAILED) {
                  compressionUploadFinished(false);
              }
          }
  
          @Override
          public void onProgressChanged(int id, long bytesCurrent, long bytesTotal) {
              int progress = Math.round(100 * ((float) bytesCurrent / bytesTotal));
              String progressPercentage = String.valueOf(progress) + "%";
              compressionUploadProgress(progress, progressPercentage);
          }
  
          @Override
          public void onError(int id, Exception ex) {
              compressionUploadFinished(false);
          }
      });
  }
  
  private void compressionUploadStarted() {
      bus.post(new CompressionUploadStartedEvent());
      updateNotification();
  }
  
  private void compressionUploadProgress(int progress, String progressPercentage) {
      bus.post(new CompressionUploadProgressEvent(progress, progressPercentage));
      mNotification.setProgress(100, progress, false);
      updateNotification();
  }
  
  private void compressionUploadFinished(boolean successfully) {
      bus.post(new CompressionUploadFinishedEvent(successfully));
      if (successfully) {
          mNotification.setContentText("Upload complete");
      } else {
          mNotification.setContentTitle("Compression Failed");
          mNotification.setContentText("Upload failed. Please try again later.");
      }
      updateNotification();
      if (!successfully) {
          VideoCompressionService.this.stopSelf();
      }
  }
  
  private void updateNotification() {
      mNotificationManager.notify(NOTIFICATION_ID, mNotification.build());
  }
  </code></pre>