2016-04-19 9 views
-1

私はイメージピッカーの意図を開き、選択したときにはUriを取得し、キャッシュディレクトリにファイルのコピーを作成し、画像の場所をピカソに渡して画像。 Googleフォトなどの一部のアプリでは、セキュリティ上の理由から実際のUrisをさまざまなアクティビティに渡すことができないため、これを行っています。私は私の活動のonCreate()方法でgetActualPathFromUri()を呼び出すAndroidサポートの使用注釈

@Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_external_photo_share); 
     ButterKnife.bind(this); 
     LogUtil.i(TAG, "onCreate called"); 
     tinyDB = new TinyDB(this); 
     if (tinyDB.getBoolean(AppConstants.LOGIN_STATE, false)) { 
      imageUri = (Uri) getIntent().getExtras().get(Intent.EXTRA_STREAM); 
      if (imageUri == null || imageUri.toString().isEmpty()) { 
       ExternalPhotoShareActivity.this.finish(); 
      } 
      String newActualPath = getActualPathFromUri(imageUri); 
      Uri newUri = null; 
      if (newActualPath != null) { 
       newUri = Uri.fromFile(new File(newActualPath)); 
      } 
      Intent intent = new Intent(ExternalPhotoShareActivity.this, AddCaptionActivity.class); 
      intent.putExtra("externalImageUri", newUri); 
      intent.putExtra("externalImagePath", newActualPath); 
      startActivity(intent); 
      ExternalPhotoShareActivity.this.finish(); 
     } else { 
      final Dialog dialog = new Dialog(ExternalPhotoShareActivity.this); 
      dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); 
      dialog.setContentView(R.layout.dialog_external_share_error); 
      dialog.setCanceledOnTouchOutside(false); 
      dialog.show(); 

      TextView goBack = (TextView) dialog.findViewById(R.id.textView86); 
      goBack.setOnClickListener(new View.OnClickListener() { 
       @Override 
       public void onClick(View v) { 
        try { 
         if(dialog != null) { 
          if(dialog.isShowing()) { 
           dialog.dismiss(); 
          } 
         } 
        } catch (final IllegalArgumentException e) { 
         // Handle or log or ignore 
        } catch (final Exception e) { 
         // Handle or log or ignore 
        } 
        ExternalPhotoShareActivity.this.finish(); 
       } 
      }); 
     } 
    } 

private String getActualPathFromUri(Uri selectedImageUri) { 
     Bitmap bitmap = null; 
     try { 
      bitmap = getBitmapFromUri(selectedImageUri); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     if (bitmap == null) { 
      return null; 
     } 

     File imageFileFolder = new File(getCacheDir(), "galleri5"); 
     if (!imageFileFolder.exists()) { 
      imageFileFolder.mkdir(); 
     } 

     FileOutputStream out = null; 

     File imageFileName = new File(imageFileFolder, "galleri5-" + System.currentTimeMillis() + ".jpg"); 
     try { 
      out = new FileOutputStream(imageFileName); 
      bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out); 
      out.flush(); 
      out.close(); 
     } catch (IOException e) { 

     } finally { 
      if (out != null) { 
       try { 
        out.close(); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
      } 
     } 
     return imageFileName.getAbsolutePath(); 
    } 

    private Bitmap getBitmapFromUri(Uri uri) throws IOException { 
     ParcelFileDescriptor parcelFileDescriptor = 
       getContentResolver().openFileDescriptor(uri, "r"); 
     assert parcelFileDescriptor != null; 
     FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor(); 
     Bitmap image = BitmapFactory.decodeFileDescriptor(fileDescriptor); 
     parcelFileDescriptor.close(); 
     return image; 
    } 

はここに同じのために私のコードです。場合によっては、ギャラリーの画像が大きい場合、画像を画面にロードするのに数秒かかることがあります。だから、私は背景の仕事が行われている間にUIを表示できるように、バックグラウンドスレッドでこれら2つのメソッドを実行することを考えました。

私は最近、Android Support Annotationsの使用を開始し、getActualPathFromUri()@WorkerThreadと注釈を付けることを試みました。しかし、私のonCreate()メソッドでは、それは赤色になっていて、このメソッドはWorker Threadから呼び出されなければならず、現在推論されているスレッドはmainであると言います。

これを行う正しい方法は何ですか?私はバックグラウンドスレッドで行うべきかどうか?ありがとう。

+0

@ jonas.koeritz私はonCreate()メソッドを追加しました。見てください。 –

答えて

2

注釈@WorkerThreadまたは@UIThreadは、メソッドにフラグを立てるためにのみ使用されます。 Android Studioは、注釈付きの制約と一致しないスレッドからメソッドが呼び出されたときにエラーを発生させます。 this documentationを参照してください。

AsyncTaskを使用してスレッディングをアドバイスする場合は、this android developers blog postを参照してください。

+0

それは問題ありませんが、どうしたらいいですか?そして私はどうしたらいいですか?私はAsyncTaskを使いたくありません。 –

+0

@AmitTiwariでは、AsyncTaskを使用する必要があります。なぜあなたはそれを省略したいですか? –

+0

私は構文が本当に好きではありません。 –

2

この場合、@WorkerThradの注釈を使用すると、getActualPathFromUri()はワーカースレッドからのみ呼び出す必要があります。 UIスレッド内で実行されているonCreate()から呼び出すと、lintはその問題を検出してフラグを立てます。

このようなメソッドにアノテーションを付けても、そのメソッドがワーカースレッド内で実行されているわけではありません。この場合のアノテーションは、特定のメソッドが特定のスレッドで呼び出されることを意味する開発者(チームで作業する場合は自分と異なる可能性がある)にフラグを立てる方法に過ぎません。

実際のワーカースレッドでそのメソッドを実際に実行する場合は、AsyncTask#doInBackgroundメソッド内で呼び出します。

EDIT:あなたがしたい使用しない場合AsyncTaskあなたがIntentServiceGcmTaskServiceやその他もろもろのように、他のAndroid糸通し機構を使用することができますが、それはjankを起こすことがあるので、あなたはUIスレッド内でそれを実行すべきではありません。

+0

ご清聴ありがとうございます。注釈を付けることで、AsyncTaskをスキップできるようになりました。 –

関連する問題