getLastNonConfigurationInstance() 的问题 - 似乎只返回 null

发布于 2024-09-25 15:25:37 字数 3941 浏览 2 评论 0原文

public class XPBN extends Activity{
private Map _map;

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

    final Map data = (Map)getLastNonConfigurationInstance();
    if (data == null) {
        Toast.makeText(this, "New Map", Toast.LENGTH_SHORT).show();
        _map = new Map(this);
    } else {
        Toast.makeText(this, "Old Map", Toast.LENGTH_SHORT).show();
        _map = (Map)data;
    }

    setContentView(_map);
}

@Override
public Object onRetainNonConfigurationInstance() {
    Toast.makeText(this, "Saving Configuration...", Toast.LENGTH_LONG).show();
    return _map;
}
}

我假设我给这个论坛帖子的标题非常彻底地说明了我遇到的问题。我还编辑了代码来尝试保存字符串对象,然后通过 getLastNonConfigurationInstance() 恢复字符串对象,只是为了看看我可以在多大程度上让它为我工作,但它似乎仍然返回 null。我没有尝试从 onStart() 或 onRestart() 或 onResume() 调用它,但从我读到的内容来看,它通常只从 onCreate(Bundle) 调用。这让我真的很困惑......:/

我认为了解一点关于我的 Map 类对象可能会有一些帮助,所以这里是其中的(一些)代码:

public class Map extends SurfaceView implements SurfaceHolder.Callback{
private MapThread _mapThread;
private int _terrain[][];
private ArrayList<Player> playerList;
private Bitmap _blueback;
private Bitmap _bluefront;
private Bitmap _blueleft;
private Bitmap _blueright;
private Bitmap _greenback;
private Bitmap _greenfront;
private Bitmap _greenleft;
private Bitmap _greenright;
private Bitmap _redfront;
private Bitmap _redback;
private Bitmap _redleft;
private Bitmap _redright;
private Bitmap _robot1;
private Bitmap _forest;
private Bitmap _grass;
private Bitmap _mountain;
private Bitmap _tree;
@SuppressWarnings("unused")
private boolean _mapLoaded = false;
private int _viewX = 0;
private int _viewY = 0;

Map(Context context){
    super(context);
    getHolder().addCallback(this);
    _mapThread = new MapThread(this);
    setFocusable(true);

    _terrain = new int[100][100];
    playerList = new ArrayList<Player>();
    addPlayer(0, 0, 0);

    _blueback = BitmapFactory.decodeResource(context.getResources(), R.drawable.blueback);
    _bluefront = BitmapFactory.decodeResource(context.getResources(), R.drawable.bluefront);
    _blueleft = BitmapFactory.decodeResource(context.getResources(), R.drawable.blueleft);
    _blueright = BitmapFactory.decodeResource(context.getResources(), R.drawable.blueright);
    _greenback = BitmapFactory.decodeResource(context.getResources(), R.drawable.greenback);
    _greenfront = BitmapFactory.decodeResource(context.getResources(), R.drawable.greenfront);
    _greenleft = BitmapFactory.decodeResource(context.getResources(), R.drawable.greenleft);
    _greenright = BitmapFactory.decodeResource(context.getResources(), R.drawable.greenright);
    _redback = BitmapFactory.decodeResource(context.getResources(), R.drawable.redback);
    _redfront = BitmapFactory.decodeResource(context.getResources(), R.drawable.redfront);
    _redleft = BitmapFactory.decodeResource(context.getResources(), R.drawable.redleft);
    _redright = BitmapFactory.decodeResource(context.getResources(), R.drawable.redright);
    _robot1 = BitmapFactory.decodeResource(context.getResources(), R.drawable.robot1);
    _forest = BitmapFactory.decodeResource(context.getResources(), R.drawable.forest);
    _grass = BitmapFactory.decodeResource(context.getResources(), R.drawable.grass);
    _mountain = BitmapFactory.decodeResource(context.getResources(), R.drawable.mountain);
    _tree = BitmapFactory.decodeResource(context.getResources(), R.drawable.tree);

    TouchScreenHandler handler = new TouchScreenHandler(); // This includes 2 other nested-class threads
    this.setOnTouchListener(handler);
}

也许对象的复杂性存在一些问题onRetainNonConfigurationInstance() 返回的可能会导致我的问题?

或者最后,我的 Manifest.xml 文件中是否有某些内容(例如“活动”或“应用程序”属性)存在问题?

如果需要任何进一步的信息,请告诉我,因为我会经常查看这篇文章,直到我能够克服路上的这个小障碍。
PS:我的 ADB 和我的设备都有这个问题。
PSS:最重要的是,非常感谢这个社区的帮助和支持,非常感谢! :D

public class XPBN extends Activity{
private Map _map;

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

    final Map data = (Map)getLastNonConfigurationInstance();
    if (data == null) {
        Toast.makeText(this, "New Map", Toast.LENGTH_SHORT).show();
        _map = new Map(this);
    } else {
        Toast.makeText(this, "Old Map", Toast.LENGTH_SHORT).show();
        _map = (Map)data;
    }

    setContentView(_map);
}

@Override
public Object onRetainNonConfigurationInstance() {
    Toast.makeText(this, "Saving Configuration...", Toast.LENGTH_LONG).show();
    return _map;
}
}

I am going to suppose that the title I gave this forum-thread states the problem I am experiencing pretty thoroughly. I have also edited the code to try to save a string object and then recover the string object through the getLastNonConfigurationInstance(), just to see to what extent I could get it to work for me, but it still seemed to return null. I have not tried calling it from onStart() or onRestart() or onResume(), but from what I have read, it is usually only called from onCreate(Bundle) anyways. This has got me really confused... :/

I figured it may be of some help to know a little about my Map class object, so here's (some of) the code from it:

public class Map extends SurfaceView implements SurfaceHolder.Callback{
private MapThread _mapThread;
private int _terrain[][];
private ArrayList<Player> playerList;
private Bitmap _blueback;
private Bitmap _bluefront;
private Bitmap _blueleft;
private Bitmap _blueright;
private Bitmap _greenback;
private Bitmap _greenfront;
private Bitmap _greenleft;
private Bitmap _greenright;
private Bitmap _redfront;
private Bitmap _redback;
private Bitmap _redleft;
private Bitmap _redright;
private Bitmap _robot1;
private Bitmap _forest;
private Bitmap _grass;
private Bitmap _mountain;
private Bitmap _tree;
@SuppressWarnings("unused")
private boolean _mapLoaded = false;
private int _viewX = 0;
private int _viewY = 0;

Map(Context context){
    super(context);
    getHolder().addCallback(this);
    _mapThread = new MapThread(this);
    setFocusable(true);

    _terrain = new int[100][100];
    playerList = new ArrayList<Player>();
    addPlayer(0, 0, 0);

    _blueback = BitmapFactory.decodeResource(context.getResources(), R.drawable.blueback);
    _bluefront = BitmapFactory.decodeResource(context.getResources(), R.drawable.bluefront);
    _blueleft = BitmapFactory.decodeResource(context.getResources(), R.drawable.blueleft);
    _blueright = BitmapFactory.decodeResource(context.getResources(), R.drawable.blueright);
    _greenback = BitmapFactory.decodeResource(context.getResources(), R.drawable.greenback);
    _greenfront = BitmapFactory.decodeResource(context.getResources(), R.drawable.greenfront);
    _greenleft = BitmapFactory.decodeResource(context.getResources(), R.drawable.greenleft);
    _greenright = BitmapFactory.decodeResource(context.getResources(), R.drawable.greenright);
    _redback = BitmapFactory.decodeResource(context.getResources(), R.drawable.redback);
    _redfront = BitmapFactory.decodeResource(context.getResources(), R.drawable.redfront);
    _redleft = BitmapFactory.decodeResource(context.getResources(), R.drawable.redleft);
    _redright = BitmapFactory.decodeResource(context.getResources(), R.drawable.redright);
    _robot1 = BitmapFactory.decodeResource(context.getResources(), R.drawable.robot1);
    _forest = BitmapFactory.decodeResource(context.getResources(), R.drawable.forest);
    _grass = BitmapFactory.decodeResource(context.getResources(), R.drawable.grass);
    _mountain = BitmapFactory.decodeResource(context.getResources(), R.drawable.mountain);
    _tree = BitmapFactory.decodeResource(context.getResources(), R.drawable.tree);

    TouchScreenHandler handler = new TouchScreenHandler(); // This includes 2 other nested-class threads
    this.setOnTouchListener(handler);
}

Perhaps there lies something in the complexity of the Object returned by onRetainNonConfigurationInstance() that might be contributing to my problems?

Or lastly is there something (like a Activity or Application property) in my Manifest.xml file that is the problem?

If any further information is required, please let me know, as I will be checking back on this post frequently until I can get past this little bump in the road.
PS: I have this problem with both ADB and my device.
PSS: most importantly, a big THANKS to this community for the help and support, as it is greatly appreciated! :D

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

旧故 2024-10-02 15:25:37

您是否确认实际上正在调用 onRetainNonConfigurationInstance() ?我看到你在里面显示了一个吐司,但你实际上并没有说它正在显示。 (为什么要使用 toast 而不是只是一个 Log.i()?)

正如文档所述,“调用此函数纯粹是为了优化,您不能依赖它的调用。”你不能相信这确实发生了。实际上,唯一发生这种情况的情况是当您的 Activity 位于前台时发生配置更改时,在这种情况下,框架会立刻调用 onRetainNonConfigurationInstance()并销毁当前实例并立即创建一个新实例,并使用可用的保留对象。您几乎无法做任何事情来阻止您返回的对象出现在新实例中...尽管我猜如果您在旧实例上调用 finish() 或类似方法,那可能会做吧。

Have you confirmed that onRetainNonConfigurationInstance() is actually being called? I see you have a toast being displayed in it, but you don't actually say it is being shown. (And why a toast instead of just a Log.i()?)

As the documentation says, "this function is called purely as an optimization, and you must not rely on it being called." You can't rely on this actually happening. The only time it will happen in fact is when a configuration change happens while your activity is in the foreground, in which case the framework will in one feel swoop call onRetainNonConfigurationInstance() and destroy the current instance and immediately create a new instance with the retained object available to it. There should be pretty much nothing you can do that would prevent the object you return from appearing in the new instance... though I guess if you call finish() or such on the old one, that might do it.

方圜几里 2024-10-02 15:25:37

不确定您的问题的解决方案,您的代码还有另一个问题。您不应该将 onRetainNonConfigurationInstance 用于保存对活动上下文的引用之类的任何内容,否则稍后会泄漏活动。

Not sure about the solution to your problem there is another problem with your code. You shouldn't use onRetainNonConfigurationInstance for anything like that holds a reference to the activity context, otherwise you will leak the activity later.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文