这是一个重复出现的问题,我过去没有找到一个好的解决方案。 我的应用程序基于具有多个子片段的单个活动。
我想做什么:
在我的一些片段中,我想用手机自带的相机应用拍照,并且都为用户显示图像,然后将其上传到我的服务器。
我现在做什么
现在,我用我的相机意图调用StartActivityForResult
,这很好。然后我从onActivityResult
收到我需要的内容,并能够在图像视图中显示拍摄的图像,并将其发送到我的服务器。
问题
有时我的onActivityResult
被调用。我的片段一直没有启动或只是通过操作系统从内存中刷新(据我了解)。
这意味着变量现在具有null-references
。
我从类似问题中读到的是OnCreateView()
应该在OnActivityResult()
之前被调用。
所以我在这里要做的是将片段状态保存到我的Arguments
和onDestroyView()
中的onSaveInstanceState()
,然后尝试恢复诸如临时{{1}之类的变量}}。然而,这里的片段似乎用一个新的Bundle启动Fragment而不是我为它创建的那个,并且由于我的相机文件为空而导致我的应用程序崩溃。
这也很难测试,因为这只是偶尔发生一次。
代码
Camera Image FilePath
来自saveState()
和onDestroyView()
onSaveInstanceState()
@Override
protected Bundle saveState() {
Bundle state = new Bundle();
state.putSerializable("tempCameraFile", tempCameraFile);
return state;
}
最后由restoreStates()
onCreateView()
我真的希望在使用碎片时我有一个明显的错误,而且有人可以帮助我。
这是一个反复出现的问题,我已经解决了从我的Activity中破坏和重新创建片段的非常难看的实现,但我现在想以正确的方式执行此操作。
答案 0 :(得分:1)
问题是你根本没有保存你的状态。
@Override
public void onSaveInstanceState(Bundle outState){
super.onSaveInstanceState(outState);
saveStateToArguments();
}
包outState
包含将保存的所有值,但包含您的方法
saveStateToArguments();
将值保存在另一个包中。
outState
和您的捆绑包不相关,因此不会保存任何内容。
此外,无需拨打saveStateToArguments();
中的onDestroyView
,因为onSaveInstanceState
会被调用。
只需将代码更改为以下内容:
@Override
public void onSaveInstanceState(Bundle outState){
super.onSaveInstanceState(outState);
outState.putSerializable("tempCameraFile", tempCameraFile);
}
并在方法onRestoreInstanceState
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
if (savedInstanceState != null) {
tempCameraFile = (File) savedInstanceState.getSerializable("tempCameraFile");
}
}
因为生命周期如下:
答案 1 :(得分:0)
使用activity启动相机应用程序并使用activity的onActivityResult来确定片段是否存在。如果它没有重新初始化片段。
getActivity().startActivityForResult(intent);
答案 2 :(得分:0)
问题是系统在低内存中杀死后台活动。
解决方案:
保存Activity
或Fragment
/**
* Handled take camera photo on low memory maybe activity on background killed, need to save state.
*/
private Uri cameraMediaOutputUri;
@Override
public Uri getCameraMediaOutputUri() {
return cameraMediaOutputUri;
}
@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
outState.putParcelable("cameraMediaOutputUri", cameraMediaOutputUri);
super.onSaveInstanceState(outState);
}
恢复状态,此处为技巧,因为Activity
上的恢复状态与Fragment
不同。
恢复活动状态
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
if (savedInstanceState !=null && savedInstanceState.containsKey("cameraMediaOutputUri"))
cameraMediaOutputUri = savedInstanceState.getParcelable("cameraMediaOutputUri");
}
恢复片段状态 Fragment Life Cycle
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if (savedInstanceState !=null && savedInstanceState.containsKey("cameraMediaOutputUri"))
cameraMediaOutputUri = savedInstanceState.getParcelable("cameraMediaOutputUri");
}