且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

在方向变化Android应用程序丢失数据

更新时间:2023-01-25 21:53:18

您将不得不重写onRetainNonConfigurationInstance并使用getLastNonConfigurationInstance保存/恢复位图。

You'll have to override onRetainNonConfigurationInstance and use getLastNonConfigurationInstance to save/restore the bitmap.

这样的:

// during onCreate(Bundle), after initialise()
bmp = getLastNonConfigurationInstance();
if(bmp!=null){ iv.setImageBitmap(bmp); }
else { /* the image was not taken yet */ }

然后在您的活动ü覆盖:

then on your activity u override:

@Override
public Object onRetainNonConfigurationInstance (){
     return bmp;
}

旋转过程中将保存位图。

That will 'save' the bitmap during rotation.

编辑:

例如,使用建议的onSaveInstanceState,将工作但不可取的,因为它会使用大量的内存和很慢但你需要的其他情形很快:

example using suggested onSaveInstanceState that will work but is not advisable because it will use a lot of memory and be very slow but you'll need for other situations soon:

public class SomethingSomething extends Activity{

    String name="";
    int page=0;

    // This is called when the activity is been created
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

            // if you saved something on outState you can recover them here
            if(savedInstanceState!=null){
                name = savedInstanceState.getString("name");
                page = savedInstanceState.getInt("page");
            }
    }

    // This is called before the activity is destroyed
@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);

            outState.putString("name", name);
            outState.putInt("page", page);
    }
}

你可以看到,这个解决方案是不利于你的情况的原因是因为的Andr​​oid包使用上,这是Android的特殊类型的序列化,可以处理原语,字符串和类的实现Parcelable(这些类实际上只包裹的原语)。即使你的位图实现Parcelable,它将采取了很多时间做的每一个字节的副本位图到捆绑,将加倍位图已经大内存的消耗。

as you can see, the reason this solution is not good for your case is because the Android Bundle used on for this is Android special type of serialization that can handle primitives, Strings and Classes that implements Parcelable (those classes really only parcel their primitives). And even thou Bitmaps do implement Parcelable, it will be taking a lot of time to do a copy of every byte on the Bitmap to the bundle and will be doubling the already big memory consumption of a Bitmap.

现在,让我们使用 setRetainInstance (略复制的例子中,你可以找到一个解决方案见\sdk\extras\android\support\samples\Support4Demos\src\com\example\android\supportv4\app\FragmentRetainInstanceSupport.Java$c$c>.

Now let's see at a solution using the setRetainInstance (slightly copied from the example you can find on \sdk\extras\android\support\samples\Support4Demos\src\com\example\android\supportv4\app\FragmentRetainInstanceSupport.Java.

请务必同时检查的例子,因为它显示了一些其他的花哨的技巧。

Make sure to also check the examples as it shows some other fancy tricks.

// This fragment will be managed by the framework but we won't built a UI for it.
public class FragRetained extends Fragment{
   public static final String TAG = "TAG.FragRetained";
   private Bitmap bitmap;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Tell the framework to try to keep this fragment around
        // during a configuration change.
        setRetainInstance(true);
    }
    public Bitmap getBitmap() { return bitmap; }
    public void setBitmap(Bitmap bmp) { bitmap = bmp; }
}

public class MyActivity extends Activity{

    private FragRetained myFragRetained;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
            // set the content view
            img = (ImageView)findViewById(R.id.byImgV);


            myFragRetained = getFragmentManger.findFragmentByTag(FragRetained.TAG);
            if(myFragRetained == null){
                myFragRetained = new FragRetained ();
            }else{
               Bitmap b = myFragRetained.getBitmap();
               if(b==null){
                  // the user still did not choose the photo
               }else{
                  img.setImageBitmap(b);
               }
            }
    }


    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == RESULT_OK) {
            Bundle extras = data.getExtras();
            bmp = (Bitmap)extras.get("data");
            iv.setImageBitmap(bmp);
            myFragRetained.setBitmap(bmp);
        }
    }

}

和确保删除行安卓configChanges =定向从您的manifest因为它可能做更多的伤害那么好,关于它的小报价:

and make sure to remove the line android:configChanges="orientation" from your manifest because it's probably doing more harm then good, a small quote about it:

请注意:使用这个属性应该避免只作为   最后一招。请阅读处理运行时更改的更多信息   关于如何妥善处理重新启动由于配置更改。

Note: Using this attribute should be avoided and used only as a last-resort. Please read Handling Runtime Changes for more information about how to properly handle a restart due to a configuration change.