Android 片段,静态变量未在 "new" 上初始化?
Android Fragment, static variables not initialized on "new"?
我一直在片段中获取一些旧数据,我基本上想从头开始构建自己。
这让我抓狂 ;)
这里是相关的代码位:在activity中,创建Fragment时:
...
Log.w(LOG_TAG, "remoteFrag is NOT available");
// Create fragment
int savePos=mDataManager.getPosition();
mDataManager.setPosition(position);
Bundle args = new Bundle();
remoteFrag = new RemoteFragment();
args.putSerializable(ExtraXMLParser, mDataManager);
Log.w(LOG_TAG, "mDataManager is " + ((mDataManager == null)? "not ":"") + "set");
remoteFrag.setArguments(args);
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.fragment_container, remoteFrag);
if(mDataManager.getPosition()!=savePos)
transaction.addToBackStack(null);
// Commit the transaction
transaction.commit();
...
我想要实现什么:在 activity 中,我想重新启动(基本上,如果我在本地 Wifi 网络中,应用程序的行为会有所不同,菜单会有所不同,并且会提供不同的选项。初始屏幕探测此类环境并适当地初始化 DataManager)。
...
Log.w(LOG_TAG,"terminating...");
leaveRemoteView();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.remove(remoteFrag);
remoteFrag=null;
mDataManager=null;
Intent intent = getBaseContext().getPackageManager().getLaunchIntentForPackage(getBaseContext().getPackageName() );
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
finish();
...
在我的remoteFrag中:
public class RemoteFragment extends Fragment implements DataManager.ProcessXMLData {
RemoteDetail remoteBottom = null;
private View thisView;
private ViewGroup thisContainer;
static private DataManager _dataManager = null;
static private boolean _dataManagerRegistered = false;
final private static String LOG_TAG = "RemoteFragment";
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// If activity recreated (such as from screen rotate), restore
// the previous article selection set by onSaveInstanceState().
// This is primarily necessary when in the two-pane layout.
Log.w(LOG_TAG, "creating RemoteFragment");
if(_dataManager == null) {
try {
_dataManager = (DataManager) getArguments().getSerializable(RemoteDisplay.ExtraXMLParser);
}
catch (NullPointerException e) {
_dataManager = null;
Log.e(LOG_TAG , "mXmlParser not passed as arguments");
}
}
else
Log.d(LOG_TAG, "dataManager was not null");
thisContainer = container;
...
如果我使用上面的第二段代码强制应用重新启动,并使用第一和第三部分启动片段,我会收到以下内容 LogCat:
03-21 14:32:37.930: D/ViewRootImpl(12915): ViewPostImeInputStage ACTION_DOWN
03-21 14:32:38.090: D/RemoteDisplay(12915): selection is 0
03-21 14:32:38.090: W/RemoteDisplay(12915): remoteFrag is NOT available
03-21 14:32:38.090: W/RemoteDisplay(12915): mDataManager is set
03-21 14:32:38.110: W/RemoteFragment(12915): creating RemoteFragment
03-21 14:32:38.110: D/RemoteFragment(12915): dataManager was not null
03-21 14:32:38.110: D/RemoteFragment(12915): will inflate now...
03-21 14:32:38.130: D/RemoteFragment(12915): finshed create view
把一切都搞砸的令人困惑的消息是 "dataManager was not null"。
这意味着该片段没有尝试从作为参数传递的 activity 接收变量 _dataManager,并且 class 顶部的初始化在使用旧值调用 OnCreateView 之前的某处被覆盖。
我在哪里可以做什么来避免这种情况?我设法按照自己的意愿对片段进行操作的唯一方法是从最近的活动中完全删除应用程序。
抱歉,如果结果有点长...;)
我刚刚找到了一个非常明显的解决方案。
我只是为 Fragment 添加了一个额外的自定义构造函数来初始化我的变量:
RemoteFragment() {
_dataManager=null;
_dataManagerRegistered = false;
}
我还是有点纳闷为什么不用自定义构造函数来做这个
我一直在片段中获取一些旧数据,我基本上想从头开始构建自己。 这让我抓狂 ;)
这里是相关的代码位:在activity中,创建Fragment时:
...
Log.w(LOG_TAG, "remoteFrag is NOT available");
// Create fragment
int savePos=mDataManager.getPosition();
mDataManager.setPosition(position);
Bundle args = new Bundle();
remoteFrag = new RemoteFragment();
args.putSerializable(ExtraXMLParser, mDataManager);
Log.w(LOG_TAG, "mDataManager is " + ((mDataManager == null)? "not ":"") + "set");
remoteFrag.setArguments(args);
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.fragment_container, remoteFrag);
if(mDataManager.getPosition()!=savePos)
transaction.addToBackStack(null);
// Commit the transaction
transaction.commit();
...
我想要实现什么:在 activity 中,我想重新启动(基本上,如果我在本地 Wifi 网络中,应用程序的行为会有所不同,菜单会有所不同,并且会提供不同的选项。初始屏幕探测此类环境并适当地初始化 DataManager)。
...
Log.w(LOG_TAG,"terminating...");
leaveRemoteView();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.remove(remoteFrag);
remoteFrag=null;
mDataManager=null;
Intent intent = getBaseContext().getPackageManager().getLaunchIntentForPackage(getBaseContext().getPackageName() );
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
finish();
...
在我的remoteFrag中:
public class RemoteFragment extends Fragment implements DataManager.ProcessXMLData {
RemoteDetail remoteBottom = null;
private View thisView;
private ViewGroup thisContainer;
static private DataManager _dataManager = null;
static private boolean _dataManagerRegistered = false;
final private static String LOG_TAG = "RemoteFragment";
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// If activity recreated (such as from screen rotate), restore
// the previous article selection set by onSaveInstanceState().
// This is primarily necessary when in the two-pane layout.
Log.w(LOG_TAG, "creating RemoteFragment");
if(_dataManager == null) {
try {
_dataManager = (DataManager) getArguments().getSerializable(RemoteDisplay.ExtraXMLParser);
}
catch (NullPointerException e) {
_dataManager = null;
Log.e(LOG_TAG , "mXmlParser not passed as arguments");
}
}
else
Log.d(LOG_TAG, "dataManager was not null");
thisContainer = container;
...
如果我使用上面的第二段代码强制应用重新启动,并使用第一和第三部分启动片段,我会收到以下内容 LogCat:
03-21 14:32:37.930: D/ViewRootImpl(12915): ViewPostImeInputStage ACTION_DOWN
03-21 14:32:38.090: D/RemoteDisplay(12915): selection is 0
03-21 14:32:38.090: W/RemoteDisplay(12915): remoteFrag is NOT available
03-21 14:32:38.090: W/RemoteDisplay(12915): mDataManager is set
03-21 14:32:38.110: W/RemoteFragment(12915): creating RemoteFragment
03-21 14:32:38.110: D/RemoteFragment(12915): dataManager was not null
03-21 14:32:38.110: D/RemoteFragment(12915): will inflate now...
03-21 14:32:38.130: D/RemoteFragment(12915): finshed create view
把一切都搞砸的令人困惑的消息是 "dataManager was not null"。 这意味着该片段没有尝试从作为参数传递的 activity 接收变量 _dataManager,并且 class 顶部的初始化在使用旧值调用 OnCreateView 之前的某处被覆盖。
我在哪里可以做什么来避免这种情况?我设法按照自己的意愿对片段进行操作的唯一方法是从最近的活动中完全删除应用程序。
抱歉,如果结果有点长...;)
我刚刚找到了一个非常明显的解决方案。 我只是为 Fragment 添加了一个额外的自定义构造函数来初始化我的变量:
RemoteFragment() {
_dataManager=null;
_dataManagerRegistered = false;
}
我还是有点纳闷为什么不用自定义构造函数来做这个