应该提供默认构造函数吗?
Should provide default constructor?
我有一个应用程序已转移到新的 android 工作室。当我尝试生成签名的 apk 时,出现此错误:
Error:(24) Error: This fragment should provide a default constructor (a public constructor with no arguments) (com.example.mike.beerportfolionewicon.BarcodeFrag) [ValidFragment]
class 是这样开始的:
public class BarcodeFrag extends Fragment implements ReadJSONResult.OnArticleSelectedListener {
private ListView lv;
View v;
SearchView searchView;
private SearchView mSearchView;
private MenuItem mSearchMenuItem;
String id;
public BarcodeFrag(String scanContent) {
id = scanContent;
}
我选择了忽略检查的选项,但它仍然不会创建 apk...
尝试将其更改为此,但同样的错误:
public class BarcodeFrag extends Fragment implements ReadJSONResult.OnArticleSelectedListener {
private ListView lv;
View v;
SearchView searchView;
private SearchView mSearchView;
private MenuItem mSearchMenuItem;
String id;
public BarcodeFrag(){}
public BarcodeFrag(String scanContent) {
id = scanContent;
}
实际上是一个不同的错误:
Error:(35) Error: Avoid non-default constructors in fragments: use a default constructor plus Fragment#setArguments(Bundle) instead [ValidFragment]
整个代码现在看起来像这样:
public class BarcodeFrag extends Fragment implements ReadJSONResult.OnArticleSelectedListener {
private ListView lv;
View v;
SearchView searchView;
private SearchView mSearchView;
private MenuItem mSearchMenuItem;
String id;
public BarcodeFrag(){}
public BarcodeFrag(String scanContent) {
id = scanContent;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
//set layout here
v = inflater.inflate(R.layout.activity_search, container, false);
setHasOptionsMenu(true);
getActivity().setTitle("Search");
//get user information
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
String userName = prefs.getString("userName", null);
String userID = prefs.getString("userID", null);
//run code with barcode content
String url = "http://api.brewerydb.com/v2/search/upc?code="+ id +"&key=xxx&format=json&withBreweries=y";
//run async task
ReadJSONResult task = new ReadJSONResult(getActivity());
task.setOnArticleSelectedListener(this);
task.execute(url);
return v;
}
@Override
public void onArticleSelected(String b, String brewery){
//code to execute on click
Fragment Fragment_one;
FragmentManager man= getFragmentManager();
FragmentTransaction tran = man.beginTransaction();
Fragment_one = new BeerTabs();
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
SharedPreferences.Editor editor = preferences.edit();
editor.putString("beerID",b);
editor.putString("breweryID",brewery);
editor.commit();
tran.replace(R.id.main, Fragment_one);//tran.
tran.addToBackStack(null);
tran.commit();
}
}
由于生命周期的原因,片段必须有一个空的构造函数。
考虑用空的替换你得到的那个,然后通过 Bundle
传递 String scanContent
。这样你就可以确保片段总是得到你的 scanContent
即使片段重新创建了自己。
Fragment fragment = new Fragment() {
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
if(getArguments() != null) {
String scanContent = getArguments().getString("scanContent");
}
}
};
Bundle bundle = new Bundle();
bundle.putString("scanContent", scanContent);
fragment.setArguments(bundle);
编辑:
来自你的Activity
:
BarcodeFrag fragment = new BarcodeFrag();
Bundle bundle = new Bundle();
bundle.putString("scanContent", scanContent);
fragment.setArguments(bundle);
在您的 Fragment
上,替换
public BarcodeFrag(String scanContent) {
id = scanContent;
}
和
public BarcodeFrag() {
}
并从 onCreateView(...)
得到 id
像这样:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if(id == null && getArguments() != null) {
String scanContent = getArguments().getString("scanContent");
this.id = scanContent;
}
.
.
.
.
}
移除
public BarcodeFrag(String scanContent) {
id = scanContent;
}
Android 中的 Fragment
不应该有非空的构造函数。相反,您可以在 Fragment
中创建一个 static
启动器工厂方法,如下所示:
public static final String SCAN_CONTENT = "param";
private String scanContent;
public static final BarcodeFrag instanceOf(String scanContent) {
BarcodeFrag fragment = new BarcodeFrag();
Bundle args = new Bundle();
args.putString(SCAN_CONTENT, scanContent);
fragment.setArguments(args);
return fragment;
}
现在,从任何其他 class、
创建 BarcodeFrag
的新实例
Fragment f = BarcodeFrag.instanceOf(scanContent)
并访问 BarcodeFrag
、
内的值 scanContent
scanContent = getArguments().getString(SCAN_CONTENT);
传递的参数可以是任何类型,即int
、float
、String
等
试试这个。这应该有效;
如果没有定义构造函数,编译器会自动创建默认构造函数。
如果任何 带有参数 的构造函数是 defined.In 情况,如果您调用默认构造函数,那么它将给出编译时错误。
public class P2 {
public P2(int a) {
}
public static void main(String[] args) {
P2 p = new P2(10);
P2 p1 = new P2(); //compile time error
}
}
为了消除编译时错误,也添加默认构造函数。
public class P2 {
public P2() { //After adding this constructor, compile time error is removed
}
public P2(int a) {
}
public static void main(String[] args) {
P2 p = new P2(10);
P2 p1 = new P2();
}
}
我有一个应用程序已转移到新的 android 工作室。当我尝试生成签名的 apk 时,出现此错误:
Error:(24) Error: This fragment should provide a default constructor (a public constructor with no arguments) (com.example.mike.beerportfolionewicon.BarcodeFrag) [ValidFragment]
class 是这样开始的:
public class BarcodeFrag extends Fragment implements ReadJSONResult.OnArticleSelectedListener {
private ListView lv;
View v;
SearchView searchView;
private SearchView mSearchView;
private MenuItem mSearchMenuItem;
String id;
public BarcodeFrag(String scanContent) {
id = scanContent;
}
我选择了忽略检查的选项,但它仍然不会创建 apk...
尝试将其更改为此,但同样的错误:
public class BarcodeFrag extends Fragment implements ReadJSONResult.OnArticleSelectedListener {
private ListView lv;
View v;
SearchView searchView;
private SearchView mSearchView;
private MenuItem mSearchMenuItem;
String id;
public BarcodeFrag(){}
public BarcodeFrag(String scanContent) {
id = scanContent;
}
实际上是一个不同的错误:
Error:(35) Error: Avoid non-default constructors in fragments: use a default constructor plus Fragment#setArguments(Bundle) instead [ValidFragment]
整个代码现在看起来像这样:
public class BarcodeFrag extends Fragment implements ReadJSONResult.OnArticleSelectedListener {
private ListView lv;
View v;
SearchView searchView;
private SearchView mSearchView;
private MenuItem mSearchMenuItem;
String id;
public BarcodeFrag(){}
public BarcodeFrag(String scanContent) {
id = scanContent;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
//set layout here
v = inflater.inflate(R.layout.activity_search, container, false);
setHasOptionsMenu(true);
getActivity().setTitle("Search");
//get user information
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
String userName = prefs.getString("userName", null);
String userID = prefs.getString("userID", null);
//run code with barcode content
String url = "http://api.brewerydb.com/v2/search/upc?code="+ id +"&key=xxx&format=json&withBreweries=y";
//run async task
ReadJSONResult task = new ReadJSONResult(getActivity());
task.setOnArticleSelectedListener(this);
task.execute(url);
return v;
}
@Override
public void onArticleSelected(String b, String brewery){
//code to execute on click
Fragment Fragment_one;
FragmentManager man= getFragmentManager();
FragmentTransaction tran = man.beginTransaction();
Fragment_one = new BeerTabs();
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
SharedPreferences.Editor editor = preferences.edit();
editor.putString("beerID",b);
editor.putString("breweryID",brewery);
editor.commit();
tran.replace(R.id.main, Fragment_one);//tran.
tran.addToBackStack(null);
tran.commit();
}
}
由于生命周期的原因,片段必须有一个空的构造函数。
考虑用空的替换你得到的那个,然后通过 Bundle
传递 String scanContent
。这样你就可以确保片段总是得到你的 scanContent
即使片段重新创建了自己。
Fragment fragment = new Fragment() {
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
if(getArguments() != null) {
String scanContent = getArguments().getString("scanContent");
}
}
};
Bundle bundle = new Bundle();
bundle.putString("scanContent", scanContent);
fragment.setArguments(bundle);
编辑:
来自你的Activity
:
BarcodeFrag fragment = new BarcodeFrag();
Bundle bundle = new Bundle();
bundle.putString("scanContent", scanContent);
fragment.setArguments(bundle);
在您的 Fragment
上,替换
public BarcodeFrag(String scanContent) {
id = scanContent;
}
和
public BarcodeFrag() {
}
并从 onCreateView(...)
得到 id
像这样:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if(id == null && getArguments() != null) {
String scanContent = getArguments().getString("scanContent");
this.id = scanContent;
}
.
.
.
.
}
移除
public BarcodeFrag(String scanContent) {
id = scanContent;
}
Android 中的 Fragment
不应该有非空的构造函数。相反,您可以在 Fragment
中创建一个 static
启动器工厂方法,如下所示:
public static final String SCAN_CONTENT = "param";
private String scanContent;
public static final BarcodeFrag instanceOf(String scanContent) {
BarcodeFrag fragment = new BarcodeFrag();
Bundle args = new Bundle();
args.putString(SCAN_CONTENT, scanContent);
fragment.setArguments(args);
return fragment;
}
现在,从任何其他 class、
创建BarcodeFrag
的新实例
Fragment f = BarcodeFrag.instanceOf(scanContent)
并访问 BarcodeFrag
、
scanContent
scanContent = getArguments().getString(SCAN_CONTENT);
传递的参数可以是任何类型,即int
、float
、String
等
试试这个。这应该有效;
如果没有定义构造函数,编译器会自动创建默认构造函数。
如果任何 带有参数 的构造函数是 defined.In 情况,如果您调用默认构造函数,那么它将给出编译时错误。
public class P2 {
public P2(int a) {
}
public static void main(String[] args) {
P2 p = new P2(10);
P2 p1 = new P2(); //compile time error
}
}
为了消除编译时错误,也添加默认构造函数。
public class P2 {
public P2() { //After adding this constructor, compile time error is removed
}
public P2(int a) {
}
public static void main(String[] args) {
P2 p = new P2(10);
P2 p1 = new P2();
}
}