应该提供默认构造函数吗?

时间:2015-02-15 12:52:42

标签: android android-studio apk

我有一个应用程序,我转移到新的Android工作室。当我尝试生成签名的apk时,我收到此错误:

Error:(24) Error: This fragment should provide a default constructor (a public constructor with no arguments) (com.example.mike.beerportfolionewicon.BarcodeFrag) [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(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();





    }
}

3 个答案:

答案 0 :(得分:1)

由于生命周期原因,片段必须具有空构造函数。 考虑用空的那个替换你得到的那个并通过String scanContent传递Bundle。通过这种方式,即使片段重新创建,您也可以确保片段始终获得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() {
}

并从id获取onCreateView(...),如下所示:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    if(id == null && getArguments() != null) {
        String scanContent = getArguments().getString("scanContent");
        this.id = scanContent;
    }
    .
    .
    .
    .
}

答案 1 :(得分:1)

删除

public BarcodeFrag(String scanContent) {
    id = scanContent;
}

Android中的Fragment永远不应该有非空的构造函数。相反,您可以在static内创建Fragment启动器工厂方法,如下所示:

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;
}

现在,要从任何其他类创建BarcodeFrag的新实例,

Fragment f = BarcodeFrag.instanceOf(scanContent)

并访问scanContent中的值BarcodeFrag

scanContent = getArguments().getString(SCAN_CONTENT);

传递的参数可以是任何类型,即intfloatString等。

试试这个。这应该有用;

答案 2 :(得分:0)

如果没有定义构造函数,那么编译器会自动创建默认构造函数。

如果定义了任何带参数构造函数。如果调用默认构造函数,则会产生编译时错误。

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();       
    }
}