2014-01-11 4 views
5

Я очень новичок в программировании на Android и экспериментирую с созданием приложения. В моем новом приложении у меня есть кнопка, которая позволяет им выбирать приложение на своем устройстве, такое как «Галерея», чтобы выбрать изображение. Затем это изображение отображается в окне просмотра изображений на экране активности. К сожалению, когда я переворачиваю свой телефон и меняю ориентацию, изображение теряется, и ему нужно снова выбрать его.Как сохранить изображение в активности Android во время изменения ориентации?

Как сохранить растровое изображение и повторно отобразить его после изменения ориентации?

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

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

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

выше функция инициализируется в моей OnCreate в ответ на нажатие кнопки, показанной в этом коде:

Button buttonLoadImage = (Button)findViewById(R.id.loadimage); 
textTargetUri = (TextView)findViewById(R.id.targeturi); 
targetImage = (ImageView)findViewById(R.id.targetimage); 

buttonLoadImage.setOnClickListener(new Button.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); 
}}); 

По существу, я просто нужно поставить этот булево в моем OnCreate и он положил изображение обратно в окно. Он также отображает текст, показывающий, где изображение находилось на устройстве, но для меня это не так важно, как возможность остаться на экране.

if (savedInstanceState != null) { 


} 

Но, похоже, они стирают данные после изменения ориентации? Я понятия не имею, как сохранить данные и восстановить их для использования в этом булевом. Я ценю любой совет, код или ссылки, которые вы можете предоставить!


UPDATE:

Спасибо Вишал Виджай и rajahsekar для быстрых и полезных ответов. Используя как ваше рекомендуемое кодирование, так и некоторый код, который я нашел из предыдущего исследования, я смог скомпилировать решение. Однако, хотя он решил первую проблему, она породила другую, которую я опишу после показа кода, который я использовал для исправления исходной проблемы.

Я обнаружил, что у меня было 2 варианта для части восстановления.

Либо я мог бы поместить это в OnCreate:

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"));R.drawable.camera_button); 
    } 

Это позволило мне иметь как изображение, а также путь к нему на устройстве, чтобы быть повторно отображается на моей деятельности.

Или я мог бы это после OnCreate

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

и сберегательной функции, которые я использовал, был

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

Чтобы уточнить, где picture_location пришли, обратно в моей функции onActivityResult я добавил строку и изменил другой, чтобы сохранить строку пути

if (resultCode == RESULT_OK){ 
    Uri targetUri = data.getData(); 
    picture_location = targetUri.toString(); 
    textTargetUri.setText(picture_location); 

Что касается variab ле инициализируется перед OnCreate,

Bitmap image; 
Bitmap bitmap; 
String picture_location; 

Теперь я понимаю, что это получило довольно длительным, но я надеюсь, что это поможет другим, которые могут иметь подобную проблему. Что касается новой проблемы, о которой я упоминал ранее, когда я вращаю свое устройство Android, он фактически сохраняет данные и повторно отображает их, как я пытался это сделать. Однако, когда я снова поворачиваю экран, возникает исходная проблема; данные, кажется, потеряны и не отображаются на экране.

Я надеюсь, что есть намного более простые исправления, так что функции сохранения и восстановления будут работать независимо от того, сколько раз меняется ориентация экрана?

Еще раз спасибо ребятам!

+0

использовать Android-запрос для этого. – Kishan

ответ

4
Bitmap image; 

public void onCreat(..){ 
    if (savedInstanceState != null) { 
     image = (Bitmap) savedInstanceState.getParcelableExtra("BitmapImage");; 
    } else { 
     image = yourBitmapImage; 
    } 
} 

@Override public void onSaveInstanceState(Bundle outState) { 
    super.onSaveInstanceState(outState); 
    outState.putExtra("BitmapImage", bitmap); 
} 
+0

Если я правильно помню, eclipse жаловался, что методы putExtra и getParcelableExtra не определены для типа Bundle. Возможно, я неправильно включил ваш код для этой ошибки. Есть ли причина для if if {} else {}, а не только if (! =) {}, Который я использовал? Будет ли использование if else исправить мою проблему, только работая для одного изменения ориентации? – DeadJohnDoe

0

Используйте onSaveInstanceState, чтобы сохранить изображение

if (savedInstanceState == null) { 
    image = R.drawable.default; 
} else { 
    // if there is a bundle, use the saved image resource (if one is there) 
    image = savedInstanceState.getInt(IMAGE_RESOURCE, R.drawable.default); 
} 

@Override 
public void onSaveInstanceState(Bundle outState) { 
    // Make sure you save the current image resource 
    outState.putInt(IMAGE_RESOURCE, image); 
    super.onSaveInstanceState(outState); 
} 

@Override 
protected void onRestoreInstanceState(Parcelable state) { 
    outState.getInt(IMAGE_RESOURCE,image); 
    super.onRestoreInstanceState(state); 
} 
+0

Есть ли причина для if if {} else {}, а не только if (! =) {}, Который я использовал? Будет ли использование if else исправить мою проблему, только работая для одного изменения ориентации? – DeadJohnDoe

-1

Добавить android:configChanges="keyboardHidden|orientation" для деятельности в файле манифеста.

+0

Плохой подход. Вы должны обрабатывать изменение ориентации вручную. –

+0

Я нашел ваш ответ как «решение» ранее, но, к сожалению, он не работает. По крайней мере, не с моей программой. – DeadJohnDoe

2

Я думаю, что это стоит слишком много, если вы сохраняете в onSaveInstanceState в Bitmap как onSaveInstanceState будет вызываться до onStop каждый раз, и Bitmap большая вещь.

Я думаю, что лучше сохранить URI в onSaveInstanceState.

Uri mUri; 
ImageView mImageView; 

protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    ... 
    if (savedInstanceState != null){ 
    mUri = savedInstanceState.getParcelable("uri"); 
    mImageView.setImageURI(mUri); 
    } 
} 


protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
    super.onActivityResult(requestCode, resultCode, data); 
    if (resultCode == RESULT_OK){ 
     Uri targetUri = data.getData(); 
     ... 
     mUri = targetUri; 
    } 
} 
public void onSaveInstanceState(Bundle outState) { 
     if (mURI !=null) { 
      outState.putParcelable("uri", mUri); 
     } 
    } 
2

Мы никогда не должны использовать выше способ сохранить наши тяжелые предметы, такие как изображения или растрового изображения всегда желательно использовать фрагменты. Посмотрите на это, как легко сохранить фрагмент https://developer.android.com/guide/topics/resources/runtime-changes.html#RetainingAnObject

1

согласно инструкции разработчика https://developer.android.com/topic/performance/graphics/cache-bitmap.html.

Рекомендованным способом является использование setRetainInstance (true) в фрагменте для сохранения изображений.

смотрите раздел на «Ручка изменения конфигурации»

изменения конфигурации среды выполнения, такие как изменение ориентации экрана, вызвать Android уничтожить и перезапустить идущую деятельность с новой конфигурацией (Для получения более подробной информации о поведении , см. раздел Обработка изменений времени выполнения). Вы хотите, чтобы вам не пришлось обрабатывать все ваши изображения снова, чтобы пользователь имел плавный и быстрый опыт при изменении конфигурации.

К счастью, у вас есть хороший кэш памяти растровых изображений, который вы создали в разделе «Использование кэша памяти».Этот кеш может быть передан в новый экземпляр активности с использованием фрагмента, который сохраняется при вызове setRetainInstance (true)). После того, как активность была воссоздана, этот сохраненный фрагмент снова подключается, и вы получаете доступ к существующему объекту кэша, позволяя быстро получать изображения и повторно заполняться в объекты ImageView.

private LruCache<String, Bitmap> mMemoryCache; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    ... 
    RetainFragment retainFragment = 
      RetainFragment.findOrCreateRetainFragment(getFragmentManager()); 
    mMemoryCache = retainFragment.mRetainedCache; 
    if (mMemoryCache == null) { 
     mMemoryCache = new LruCache<String, Bitmap>(cacheSize) { 
      ... // Initialize cache here as usual 
     } 
     retainFragment.mRetainedCache = mMemoryCache; 
    } 
    ... 
} 

class RetainFragment extends Fragment { 
    private static final String TAG = "RetainFragment"; 
    public LruCache<String, Bitmap> mRetainedCache; 

    public RetainFragment() {} 

    public static RetainFragment findOrCreateRetainFragment(FragmentManager fm) { 
     RetainFragment fragment = (RetainFragment) fm.findFragmentByTag(TAG); 
     if (fragment == null) { 
      fragment = new RetainFragment(); 
      fm.beginTransaction().add(fragment, TAG).commit(); 
     } 
     return fragment; 
    } 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setRetainInstance(true); 
    } 
} 
Смежные вопросы