2016-02-25 45 views
8

Posiadam kartę RecyclerView z wieloma różnymi widokami. Jeden z ViewHolders zawiera ImageView, który musi być w stanie zrobić zdjęcie, zmienić jego rozmiar, a następnie wyświetlić. Dla modułowości chcę, aby ViewHolder był samowystarczalny: to, a nie działanie nadrzędne, powinno zajmować się wszystkim, co dotyczy procesu robienia i wyświetlania zdjęć. Również ścieżka do pliku jest stała (nigdy się nie zmieni). W rzeczywistości jest to /storage/emulated/0/com.company.app/myst/cat.jpg. W rezultacie, oto moja implementacja metody ImageView o nazwie Image23.Aparat nie zastępuje starego obrazu, jeśli zmienia się orientacja

@Override 
public void onClick(View v) { 
    final FragmentManager fm = ((MyActivity) getContext()).getSupportFragmentManager(); 
    Fragment auxiliary = new Fragment() { 
     @Override 
     public void onActivityResult(int requestCode, int resultCode, Intent data) { 
      resizeResaveAndDisplayPhoto(); 
      super.onActivityResult(requestCode, resultCode, data); 
      fm.beginTransaction().remove(this).commit(); 
     } 
    }; 
    fm.beginTransaction().add(auxiliary, "FRAGMENT_TAG").commit(); 
    fm.executePendingTransactions(); 

    Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 
    if (null != takePictureIntent.resolveActivity(view.getContext().getPackageManager())) { 
     ((MyActivity)view.getContext()).setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); 
     takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile)); 
     auxFragment.startActivityForResult(takePictureIntent, Constants.REQUEST_CODE_PHOTO); 
    } 
} 

Kiedy resizeResaveAndDisplayPhoto nazywa się ją wykonuje następującą AsyncTask

public static class ResizeThenLoadImageTask extends AsyncTask<String, Void, Bitmap> { 

    private final WeakReference<ImageView> imageViewWeakReference; 
    private final WeakReference<File> fileWeakReference; 
    private final WeakReference<Context> weakContext; 
    private final int reqHeight; 
    private final int reqWidth; 

    public ResizeThenLoadImageTask(Context context, ImageView imageView, File file, int reqHeight, int reqWidth) { 
     weakContext = new WeakReference<Context>(context); 
     imageViewWeakReference = new WeakReference<>(imageView); 
     fileWeakReference = new WeakReference(file); 
     this.reqHeight = reqHeight; 
     this.reqWidth = reqWidth; 
    } 

    @Override 
    public Bitmap doInBackground(String... params) { 
     File file = fileWeakReference.get(); 
     Bitmap bitmap = null; 
     if (null != file) { 
      bitmap = ImageUtils.reduceImageSize(file, reqHeight, reqWidth); 
      ImageUtils.saveBitmapToGivenFile(bitmap, file); 
     } 
     return bitmap; 
    } 

    @Override 
    public void onPostExecute(Bitmap bitmap) { 
     if (null != imageViewWeakReference && null != fileWeakReference) { 
      ImageView imageView = imageViewWeakReference.get(); 
      File file = fileWeakReference.get(); 
      if (null != imageView) { 
       if (null != bitmap) { 
        imageView.setImageBitmap(bitmap); 
       } 
       else { 
        imageView.setImageResource(R.drawable.photo); 
       } 
       imageView.postDelayed(new Runnable() { 
        @Override 
        public void run() { 
         if (null != weakContext.get()) { 
          ((MyActivity) weakContext.get()).setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED); 
         } 
        } 
       }, 10000); 
      } 
     } 
    } 
} 

Można zauważyć, że ja zablokować orientację przed zrobieniem zdjęcia i odblokować 10 sekund po wyświetleniu zdjęcia. Ta sztuczka jest częścią mojego rozwiązywania problemów. Oto sytuacja. Opisany powyżej system działa bardzo dobrze. Problemy występują w następującym przypadku:

  • Załóżmy, że mam już zdjęcie w ImageView, ale chcę je zastąpić.
  • Klikam więc na ImageView, aby zrobić nowe zdjęcie.
  • Jeśli obrócę urządzenie, aby zrobić nowe zdjęcie, to po powrocie nowe zdjęcie wyświetla się na krótko przed powrotem starego zdjęcia.
  • Więc blokuję orientację, aby zobaczyć, co się dzieje. Oto co znalazłem.
  • Nowe zdjęcie wyświetla się tak długo, jak długo blokuję orientację. Jak tylko orientacja zostanie odblokowana (10 sekund), stare zdjęcie wraca.
  • Jeśli zostawiam aktywność i zwroty, stare zdjęcie będzie nadal wyświetlane.
  • Po całkowitym zamknięciu aplikacji, a następnie powrocie, widzę nowe zdjęcie.
+0

Używam więc jednej trzeciej moich punktów, aby zadać to pytanie. Proszę podać sensowne odpowiedzi. –

+0

masz do czynienia z tym problemem tylko w orientacji lub tylko domyślny obraz jest wyświetlany cały czas? –

+0

Pokaż nam kod, w którym po raz pierwszy został utworzony lub odtworzony "Activity" po zmianie orientacji, gdzie ładujesz mapę bitową z pliku do 'ImageView'. –

Odpowiedz

0

Po obróceniu urządzenia odtwarzane jest działanie bieżące, a także dołączona do niego funkcja asyncTask, prawdopodobnie powodująca wyciek.

Prawdopodobnie trzeba wywołać funkcję asyncTask w usłudze zamiast w działaniu, aby asyncTask był dołączony do cyklu życia usługi.

+0

Twoja odpowiedź mija się z celem. Nie wyjaśnia, dlaczego zawartość pliku cofa się do poprzedniego zdjęcia. Proszę przeczytać całe pytanie. –

+0

poprzedni język był zbyt mylący. Więc zredagowałem tekst. –

+0

Nie jestem pewien, czy moja odpowiedź rozwiązuje twój problem, prawda? Jeśli tak, zredaguję swoją odpowiedź, próbując wyjaśnić, dlaczego zawartość pliku cofa się do poprzedniego zdjęcia, jeśli nie, nie ma sensu próbować tego wyjaśnić. – cherif