Изображение на ImageView потеряно после уничтожения Activity

Я пытаюсь создать приложение, в котором я могу позволить пользователю выбрать изображение для отображения в своем профиле. Я могу просматривать и устанавливать выбранное изображение в режиме просмотра изображений. Но изображение теряется после уничтожения активности. Я пытался реализовать onSaveInstanceState, но все равно. Мне интересно, правильно ли я его использую. Надеюсь, вы сможете помочь такому новичку, как я. Заранее спасибо. Вот код, который я использую:

public class AccountFragment extends Fragment implements OnClickListener {
private LoginDataBaseAdapter loginDataBaseAdapter;
Bitmap image;
Bitmap bitmap;
String picture_location;
TextView textTargetUri;
ImageView targetImage;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {


        View rootView = inflater.inflate(R.layout.fragment_account, container, false);


            textTargetUri = (TextView) rootView.findViewById(R.id.targeturi);

            targetImage=(ImageView) rootView.findViewById(R.id.profpic);

            targetImage.setOnClickListener(new ImageView.OnClickListener(){
            @Override
            public void onClick(View arg0) {
                Intent   intent = new Intent(Intent.ACTION_PICK,
                android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                startActivityForResult(intent, 0);
            }});

            if (savedInstanceState != null) {
                //if there is a bundle, use the saved image resource (if one is there)
                image = savedInstanceState.getParcelable("BitmapImage");
                targetImage.setImageBitmap(image);
                textTargetUri.setText(savedInstanceState.getString("path_to_picture"));
            } 



        return rootView;



    }

    @Override 
    public void onSaveInstanceState(Bundle savedInstanceState){
        super.onSaveInstanceState(savedInstanceState);
        savedInstanceState.putParcelable("BitmapImage", bitmap);
        savedInstanceState.putString("path_to_picture", picture_location);
    }


    @Override
    public void onActivityResult( int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (resultCode == Activity.RESULT_OK){
            Uri targetUri = data.getData();
            picture_location = targetUri.toString();
            textTargetUri.setText(targetUri.toString());
            Bitmap bitmap;
            try {
                bitmap = BitmapFactory.decodeStream(getActivity().getContentResolver().openInputStream(targetUri));
                targetImage.setImageBitmap(bitmap);
            } 
            catch (FileNotFoundException e){
                e.printStackTrace();
            }
        }   
    }

    @Override
    public void onClick(View arg0) {
        // TODO Auto-generated method stub

    }}

Кстати, вы могли заметить, что вместо использования onRestoreInstanceState после oncreate я попытался использовать другой подход. Я нашел ответ на другой вопрос, который вы также можете реализовать внутри файла oncreate. Я использовал его, поскольку всякий раз, когда я объявляю функцию onRestoreInstanceState, меня просят удалить аннотацию @Override.

@Override 
protected void onRestoreInstanceState(Bundle savedInstanceState){       
            image = savedInstanceState.getParcelable("BitmapImage");
            targetImage.setImageBitmap(image);
            textTargetUri.setText(savedInstanceState.getString("path_to_picture"));
    }

person DEADPOOL    schedule 29.08.2014    source источник
comment
Вы хотите сохранить изображение, когда пользователь вернется?   -  person Bharath Mg    schedule 29.08.2014
comment
Если вы хотите сохранить изображение даже после того, как пользователь покинет приложение, вам следует сохранить путь к файлу в SharedPrefs или БД.   -  person codeMagic    schedule 29.08.2014


Ответы (4)


Использование onSaveInstanceState и onCreate/onRestoreInstanceState предназначено для краткосрочного сохранения состояния активности, но не для постоянного хранения данных приложения.

Вы можете прочитать о onSaveInstanceState здесь

Вы можете прочитать о постоянном хранилище здесь

codeMagic предложил использовать SharedPrefs (см. ссылку на постоянное хранилище) для вашего долгосрочного постоянного хранилища. Если вы хотите сделать это, я бы предложил сохранить URI изображения (в ссылке есть хороший пример того, как это сделать) в вашем методе onActivityResult, а затем вызвать метод для чтения SharedPref и загрузить изображение, которое вы можете вызвать из onCreate, а также из onActivityResult.

Вы также можете сохранить свою собственную копию изображения/растрового изображения в собственном внутреннем хранилище вашего приложения (см. ссылку на постоянное хранилище).

person Richard Shurtz    schedule 29.08.2014

если вы не заканчиваете действие, вы можете использовать onSavedInstance() для сохранения значения picture_location и привязать его обратно либо в onCreate(SavedInst)/onRestore() из значения picture_location.

person Jithu    schedule 29.08.2014

В случае Bitmaps Instance State не рекомендуется сохранять информацию о выбранном изображении.

Объяснение можно найти здесь: Обработка изменений конфигурации

Я много писал об этом в блоге здесь: Сохранить выбранное Изображение во время поворота экрана

Ниже я вставляю свою реализацию иллюстрированного решения:

1 - Создайте фрагмент и настройте его для сохранения в памяти.

import android.graphics.Bitmap;
import android.os.Bundle;
import android.support.v4.app.Fragment;

public class ImageRetainingFragment extends Fragment {
    private Bitmap selectedImage;

    @Override    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // retain this fragment        
        setRetainInstance(true);
}

public void setImage(Bitmap selectedImage) {
    this.selectedImage = selectedImage;
}

public Bitmap getImage() {
    return this.selectedImage;
}
}

2 - Используйте это в своей деятельности

private static final String FRAGMENT_NAME = "imageFragment";


protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    ....

    initializeImageRetainingFragment();
    tryLoadImage();
}


private void initializeImageRetainingFragment() {
    // find the retained fragment on activity restarts    
    FragmentManager fragmentManager = getSupportFragmentManager();
    this.imageRetainingFragment = (ImageRetainingFragment)  fragmentManager.findFragmentByTag(FRAGMENT_NAME);
    // create the fragment and bitmap the first time   
    if (this.imageRetainingFragment == null) {
         this.imageRetainingFragment = new ImageRetainingFragment();
         fragmentManager.beginTransaction()
         // Add a fragment to the activity state. 
         .add(this.imageRetainingFragment, FRAGMENT_NAME)
         .commit();
   }
}
private void tryLoadImage() {
   if (this.imageRetainingFragment == null) {
       return;
   }

   Bitmap selectedImage = this.imageRetainingFragment.getImage();
      if (selectedImage == null) {
        return;
      }

      ImageView selectedImageView = (ImageView)findViewById(R.id.selectedImage);
      selectedImageView.setImageBitmap(selectedImage);
}
person ilmatte    schedule 01.04.2016
comment
Привет! Знаете ли вы, как сохранить растровое изображение в хранилище до того, как оставшийся фрагмент будет уничтожен операционной системой? - person Boris Salimov; 08.05.2018

1)// манифест.xml

2)//общедоступный класс MainActivity расширяет AppCompatActivity, реализует LocationListener{...

SharedPreferences.Editor editor;

3)//защищенная пустота onCreate(Bundle saveInstanceState){ ...

    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) !=
            PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 3);
    }

4)//ОБЩИЕ ПРЕДПОЧТЕНИЯ SharedPreferences pref = getApplicationContext().getSharedPreferences(MyPref, getApplicationContext().MODE_PRIVATE); редактор = pref.edit();

5)//УСТАНОВИТЬ ПУТЬ К ИЗОБРАЖЕНИЮ if (pref.getString(mydraw, null) != null) {

        img6.setImageURI(Uri.parse(pref.getString("mydraw", null)));

    } else {
        //set default image
        img6.setImageResource(R.drawable.poseidon);
    }

6) // protected void onActivityResult (int requestCode, int resultCode, @Nullable Intent data) {...

если (код_запроса == 100) { если (код_результата == RESULT_OK) {

            img6.setImageURI(data.getData());

            //save URI as string
            editor.putString("mydraw", data.getData().toString());
            editor.commit(); // commit changes

        }
    }
person Michael Papaioannou    schedule 15.02.2021