2016-04-19 9 views
-1

Ich habe eine Aktivität, wo ich eine Bildauswahl Intent öffnen und wenn ich die ausgewählte Uri, ich eine Kopie der Datei im Cache-Verzeichnis und dann übergeben Sie den Speicherort des Bildes an Picasso, um die geladen Bild. Ich mache das, weil einige Apps wie Google Fotos aus Sicherheitsgründen nicht zulassen, dass der eigentliche Uris zu verschiedenen Aktivitäten weitergeleitet wird.Verwenden der Android-Unterstützung Anmerkungen

Hier ist mein Code für das gleiche:

@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; 
    } 

I getActualPathFromUri() rufe in onCreate() Methode meiner Tätigkeit. Manchmal, wenn die Bilder aus der Galerie groß sind, dauert es einige Sekunden, um das Bild auf den Bildschirm zu laden. Also dachte ich darüber nach, diese beiden Methoden im Hintergrund-Thread auszuführen, so dass ich die Benutzeroberfläche anzeigen konnte, während die Hintergrundarbeit erledigt war.

Ich begann vor kurzem mit Android Support Annotations und versuchte, die getActualPathFromUri() mit @WorkerThread zu kommentieren. Aber in meiner onCreate() Methode, es markiert es rot und sagt, dass diese Methode von Worker Thread aufgerufen werden soll, derzeit abgeleiteten Thread ist Haupt.

Was ist der richtige Weg, dies zu tun? Sollte ich es sogar im Hintergrund tun oder nicht? Vielen Dank.

+0

@ jonas.koeritz Ich habe die onCreate() Methode hinzugefügt. Bitte guck dir das an. –

Antwort

2

Die Anmerkungen @WorkerThread oder @UIThread werden nur zum Kennzeichnen einer Methode verwendet. Android Studio löst einen Fehler aus, wenn Ihre Methode von einem Thread aufgerufen wird, der nicht mit der mit Anmerkungen versehenen Einschränkung übereinstimmt. Siehe this documentation.

Hinweise zum Einfädeln mit AsyncTask siehe this android developers blog post.

+0

Das ist in Ordnung, aber was soll ich tun? Und wie soll ich es machen? Ich möchte AsyncTask nicht verwenden. –

+0

@AmitTiwari müssen Sie eine AsyncTask verwenden. Warum solltest du das weglassen? –

+0

Ich mag die Syntax nicht wirklich. –

2

In diesem Fall mit der Anmerkung @WorkerThrad Sie sagen, dass getActualPathFromUri() sollte nur von einem Worker-Thread aufgerufen werden. Wie Sie es von onCreate() aufrufen, die innerhalb des UI-Thread ausgeführt wird, erkennt Lint das Problem und kennzeichnet es.

Die Tatsache, dass Sie die Methode so annotieren, bedeutet nicht, dass Sie die Methode innerhalb eines Worker-Threads ausführen. Annotation ist in diesem Fall nur eine Möglichkeit, den Entwickler (der bei der Arbeit in einem Team anders als Sie selbst sein könnte) zu kennzeichnen, dass eine bestimmte Methode in einem bestimmten Thread aufgerufen werden soll.

Wenn Sie diese Methode tatsächlich in einem tatsächlichen Worker-Thread ausführen möchten, rufen Sie sie einfach innerhalb einer AsyncTask#doInBackground-Methode auf.

EDIT: wenn Sie wollen nicht AsyncTask verwenden Sie einen anderen Android Fädelmechanik verwenden können, wie IntentService, GcmTaskService und so weiter, aber man sollte es innerhalb des UI-Thread nicht ausgeführt werden, da es jank verursachen kann.

+0

danke für die Klärung. Ich dachte, es würde mir erlauben, AsyncTask zu überspringen. –

Verwandte Themen