难道片段真的需要一个空的构造? [英] Do fragments really need an empty constructor?
问题描述
我有多个参数的构造函数的片段,一切testphase过程中工作得很好,但现在经过约300名用户下载的应用程序,我有一个occurence是例外的:
I have a fragment with a Constructor with multiple arguments, everything worked fine during testphase but now after about 300 users downloaded the app, i have ONE occurence of that exception:
android.support.v4.app.Fragment$InstantiationException: Unable to instantiate fragment
make sure class name exists, is public, and has an empty constructor that is public
我的意思是我可以提供不同的构造,但并不作过多的意义,因为我将不得不调用其他方法来真正建立片段。
I mean i could provide a different Constructor but that doesn't make too much sense since i would then have to call another method to really set up the Fragment.
我很好奇,为什么会发生零星的,而不是总是,也许即时通讯使用零散Viewpager绝对错误的,因为我实例化所有碎片自己,并将它们保存到内部的活动列表。我不使用 FragmentManager
交易的东西,距今约碎片Viewpager的例子也不是很清楚这一点,最终一切都能正常工作。
I'm curious as to why that is happening sporadically and not always and maybe im using the Fragmented Viewpager just wrong, because i instantiate all the fragments myself and save them into a list inside the activity. I don't use the FragmentManager
transaction stuff, since the example about Fragmented Viewpager was not very clear about that and in the end everything worked fine.
推荐答案
是的,他们做的。
您真的不应该是反正覆盖的构造。你应该有一个定义的的newInstance()
静态方法,并通过参数传递任何参数(包)
You shouldn't really be overriding the constructor anyway. You should have a newInstance()
static method defined and pass any parameters via arguments (bundle)
例如:
public static final AlertFragment newInstance(int title, String message)
{
AlertFragment f = new AlertFragment();
Bundle bdl = new Bundle(2);
bdl.putInt(EXTRA_TITLE, title);
bdl.putString(EXTRA_MESSAGE, message);
f.setArguments(bdl);
return f;
}
当然抓住的args是这样的:
And of course grabbing the args this way:
@Override
public void onCreate(Bundle savedInstanceState)
{
title = getArguments().getInt(EXTRA_TITLE);
message = getArguments().getString(EXTRA_MESSAGE);
//...
//etc
//...
}
然后你会实例化从片段经理像这样:
Then you would instantiate from your fragment manager like so:
public onCreate(Bundle savedInstanceState) {
if(savedInstanceState == null){
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.content,AlertFragment.newInstance(
R.string.alert_title,
"Oh noes an error occured!")
)
.commit();
}
}
这样,如果分离并重新连接对象的状态可以通过参数进行存储。就像附在意图包。
This way if detached and re-attached the object state can be stored through the arguments. Much like bundles attached to Intents.
原因 - 额外的阅读
我想我会为人们想知道为什么。
I thought I would explain why for people wondering why.
如果您检查:<一href="https://android.googlesource.com/platform/frameworks/support/+/refs/heads/master/v4/java/android/support/v4/app/Fragment.java">https://android.googlesource.com/platform/frameworks/support/+/refs/heads/master/v4/java/android/support/v4/app/Fragment.java
您将看到实例化(..)
在片段
类方法调用的newInstance
方法。 <一href="http://docs.oracle.com/javase/6/docs/api/java/lang/Class.html#newInstance()">http://docs.oracle.com/javase/6/docs/api/java/lang/Class.html#newInstance()解释了为什么,在实例化时它会检查该访问是公开
而这种类加载器允许它访问。
You will see the instantiate(..)
method in the Fragment
class calls the newInstance
method. http://docs.oracle.com/javase/6/docs/api/java/lang/Class.html#newInstance() Explains why, upon instantiation it checks that the accessor is public
and that that class loader allows access to it.
这是一个pretty的讨厌的方法,这一切的一切,但它允许 FragmentManger
杀死并重新创建片段
与状态。 (Android的子系统做类似的事情,与活动
)。
It's a pretty nasty method all in all, but it allows the FragmentManger
to kill and recreate Fragments
with states. (The Android subsystem does similar things with Activities
).
示例类
我被问了很多关于调用的newInstance
,(不与类方法混淆。这整个阶级的例子应该显示的用法。
I get asked alot about calling newInstance
,(do not confuse this with the class method. This whole class example should show the usage.
/**
* Created by chris on 21/11/2013
*/
public class StationInfoAccessibilityFragment extends BaseFragment implements JourneyProviderListener {
public static final StationInfoAccessibilityFragment newInstance(String crsCode) {
StationInfoAccessibilityFragment fragment = new StationInfoAccessibilityFragment();
final Bundle args = new Bundle(1);
args.putString(EXTRA_CRS_CODE, crsCode);
fragment.setArguments(args);
return fragment;
}
// Views
LinearLayout mLinearLayout;
/**
* Layout Inflater
*/
private LayoutInflater mInflater;
/**
* Station Crs Code
*/
private String mCrsCode;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mCrsCode = getArguments().getString(EXTRA_CRS_CODE);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mInflater = inflater;
return inflater.inflate(R.layout.fragment_station_accessibility, container, false);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mLinearLayout = (LinearLayout)view.findViewBy(R.id.station_info_accessibility_linear);
//Do stuff
}
@Override
public void onResume() {
super.onResume();
getActivity().getSupportActionBar().setTitle(R.string.station_info_access_mobility_title);
}
// Other methods etc...
}
这篇关于难道片段真的需要一个空的构造?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!