【问题标题】:Image on ImageView lost after Activity is destroyedActivity 销毁后 ImageView 上的图像丢失
【发布时间】:2021-02-15 22:28:32
【问题描述】:

我正在尝试制作一个应用程序,让用户可以选择一张图片显示在他们的个人资料上。我可以在 imageview 上浏览和设置他们选择的图像。但是一旦活动被破坏,图像就会丢失。我试图实现 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

    }}

顺便说一句,您可能已经注意到,我尝试使用不同的方法,而不是在 oncreate 之后使用 onRestoreInstanceState。我从另一个问题中找到了答案,您也可以在 oncreate 中实现它。我使用它是因为每当我声明函数 onRestoreInstanceState 时,都会要求我删除 @Override 注释。

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

【问题讨论】:

  • 用户返回后是否要保存图像?
  • 如果您想在用户离开应用后仍保留图像,那么您应该将文件路径保存在SharedPrefs 或 DB 中。

标签: android android-fragments imageview onrestoreinstancestate


【解决方案1】:

使用 onSaveInstanceState 和 onCreate/onRestoreInstanceState 用于短期活动状态保存 - 但不能用于应用程序数据的持久存储。

你可以阅读关于 onSaveInstanceState here

您可以阅读有关持久存储的信息here

codeMagic 建议使用 SharedPrefs(请参阅持久存储链接)作为您的长期持久存储。如果你想这样做,我建议在你的 onActivityResult 方法中保存图像 URI(链接有一个很好的例子),然后调用一个方法来读取 SharedPref 并加载你可以调用的图像onCreate 以及来自 onActivityResult。

您可能还希望将自己的图像/位图副本存储在应用程序自己的内部存储中(请参阅持久存储链接)。

【讨论】:

    【解决方案2】:

    如果您没有完成活动,您可以使用onSavedInstance() 存储picture_location 值并将其绑定回onCreate(SavedInst)/onRestore() 中的picture_location 值。

    【讨论】:

      【解决方案3】:

      如果位图实例状态不是保存所选图像信息的建议方式。

      你可以在这里找到解释:Handling configuration Changes

      我在这里写了很多关于它的博客:Retain selected Image during Screen Rotation

      下面我粘贴我的图解解决方案的实现:

      1 - 创建一个 Fragment 并将其配置为保留在内存中

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

      【讨论】:

      • 您好!您知道如何在保留的片段被操作系统销毁之前将位图保存到存储中吗?
      【解决方案4】:

      1)// manifest.xml

      2)//public class MainActivity extends AppCompatActivity implements LocationListener{...

      SharedPreferences.Editor editor;
      

      3)//protected void onCreate(Bundle savedInstanceState){ ...

          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){ if (resultCode == RESULT_OK) {

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

      【讨论】:

        猜你喜欢
        • 2022-12-16
        • 1970-01-01
        • 1970-01-01
        • 2014-12-02
        • 1970-01-01
        • 2016-06-14
        • 1970-01-01
        • 2013-01-25
        • 1970-01-01
        相关资源
        最近更新 更多