简体   繁体   中英

Why am I getting "java.lang.InstantiationException has no zero argument constructor"?

I saw other related post to it, but those posts couldn't solve my problem. I am making a Time Table app. I have made a constructor of my TimeTable class that I will use in my Log class.

From the TimeTable class, I want to get the value of strFileName and have this value assigned to a particular element of the logs ArrayList that is in the Log class. logs ArrayList is an ArrayList of log , where each log is cardView and a log has a TextView to which I want to assign strFileName from TimeTable .

Here is the TimeTable Class -

package com.example.timetable;

import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import java.util.ArrayList;

public class TimeTable extends AppCompatActivity implements saveFolderDialog.saveFolderDialogListener{

    private RecyclerView recyclerView;
    private RecyclerView.Adapter mAdapter;
    private RecyclerView.LayoutManager layoutManager;

    Button addBtn;
    TextView day;
    TextView date;

    ArrayList<row> rows = new ArrayList<>();
    private int indexOfEachRow;

    String strFileName;
    public TimeTable() {
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.time_table);

        setupAppElements();
        createRecyclerView();

        addEmptyRow();
        indexOfEachRow = rows.get(rows.size() - 1).getIndex();

        addBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //check whether the last row's credentials are empty or not
                if(rows.get(rows.size()-1).getTasksName().matches("") || rows.get(rows.size()-1).getHours() == 0) {
                    Toast.makeText(TimeTable.this, "Fill out previous row's content", Toast.LENGTH_SHORT).show();
                    return;
                }

                int totalHours = 0;
                for(int i=0; i < rows.size(); i++){
                    totalHours = totalHours + (rows.get(i).getHours());
                }

                if (totalHours <= 24) {
                    addEmptyRow();
                    mAdapter.notifyItemInserted(rows.size());
                } else {
                    Toast.makeText(TimeTable.this, "Total hours have exceeded 24 hours", Toast.LENGTH_SHORT).show();
                }
            }
        });

    }

    public void createRecyclerView(){
        recyclerView = (RecyclerView) findViewById(R.id.list);
        recyclerView.setHasFixedSize(true);
        layoutManager = new LinearLayoutManager(this);
        recyclerView.setLayoutManager(layoutManager);
        mAdapter = new TimeTableAdapter(rows, TimeTable.this);
        recyclerView.setAdapter(mAdapter);
    }

    public void addEmptyRow(){

        rows.add(new row());
        for(int i = 0; i < rows.size(); i++) {
            rows.get(rows.size() - 1).setIndex(indexOfEachRow+i);
        }
        rows.get(rows.size() - 1).setTasksName("");

    }

    public void setupAppElements(){
        addBtn = findViewById(R.id.add);
        day = findViewById(R.id.day);
        date = findViewById(R.id.date);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu){
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.main_menu, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {

        switch(item.getItemId()){

            case R.id.collectData:
                //connect the total hours with the pie chart
                savePopUpWindow();
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }

    public void savePopUpWindow(){

        saveFolderDialog sFD = new saveFolderDialog();
        sFD.show(getSupportFragmentManager(),"save folder dialogue");

    }

    public String getStrFileName() {
        return strFileName;
    }

    @Override
    public void assignFolderName(String fileName) {
        strFileName = fileName;
    }
}

The last method in the above class, assignFolderName , come from another class called saveFolderDialog and here is the code for it -

package com.example.timetable;

import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.EditText;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatDialogFragment;

public class saveFolderDialog extends AppCompatDialogFragment {


    private AlertDialog.Builder dialogBuilder;
    private saveFolderDialogListener listener;

    private EditText fileName;


    @NonNull
    @Override
    public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {

        dialogBuilder = new AlertDialog.Builder(getActivity());
        LayoutInflater inflater  = getActivity().getLayoutInflater();
        View view = inflater.inflate(R.layout.save_popup_window, null);

        dialogBuilder.setView(view)
                     .setTitle("")
                     .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                         @Override
                         public void onClick(DialogInterface dialogInterface, int i) {

                         }
                     })
                    .setPositiveButton("Save", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialogInterface, int i) {

                            String strFileName = fileName.getText().toString();
                            listener.assignFolderName(strFileName);
                        }
                    });


        fileName = view.findViewById(R.id.fileName);

        return dialogBuilder.create();

    }

    @Override
    public void onAttach(@NonNull Context context) {
        super.onAttach(context);

        try {
            listener = (saveFolderDialogListener) context;
        }
        catch (ClassCastException e){
            throw new ClassCastException(context.toString() +
                    "must implement the saveFolderDialogListener >:(");
        }
    }

    public interface saveFolderDialogListener{

        void assignFolderName(String fileName);

    }

}

Here is the Log class -

package com.example.timetable;

import android.os.Bundle;

import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import java.util.ArrayList;

public class Log extends AppCompatActivity {

    private RecyclerView recyclerView;
    private RecyclerView.Adapter mAdapter;
    private RecyclerView.LayoutManager layoutManager;

    ArrayList<logsRow> logs;

    public Log (ArrayList<logsRow> logs){
        this.logs = logs;
    }

    @Override
    public void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        setContentView(R.layout.log_sheet);

        createRecyclerView();
        addLog();

    }

    public void createRecyclerView(){
        recyclerView = (RecyclerView) findViewById(R.id.log_sheet);
        recyclerView.setHasFixedSize(true);
        layoutManager = new LinearLayoutManager(this);
        recyclerView.setLayoutManager(layoutManager);
        mAdapter = new LogAdapter(logs, Log.this);
        recyclerView.setAdapter(mAdapter);
    }

    public void addLog(){
        TimeTable timeTable = new TimeTable();
        String fileName = timeTable.getStrFileName();
        logs.add(new logsRow(fileName));
    }
}

The problem arises in my addLog method in my Log class. I am getting an error and here is the stack trace for it -

2022-06-25 11:52:31.909 1640-1640/com.example.timetable E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.timetable, PID: 1640
    java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.example.timetable/com.example.timetable.Log}: java.lang.InstantiationException: java.lang.Class<com.example.timetable.Log> has no zero argument constructor
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3545)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3792)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:103)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2210)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loopOnce(Looper.java:201)
        at android.os.Looper.loop(Looper.java:288)
        at android.app.ActivityThread.main(ActivityThread.java:7839)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
     Caused by: java.lang.InstantiationException: java.lang.Class<com.example.timetable.Log> has no zero argument constructor
        at java.lang.Class.newInstance(Native Method)
        at android.app.AppComponentFactory.instantiateActivity(AppComponentFactory.java:95)
        at androidx.core.app.CoreComponentFactory.instantiateActivity(CoreComponentFactory.java:45)
        at android.app.Instrumentation.newActivity(Instrumentation.java:1273)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3532)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3792) 
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:103) 
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) 
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2210) 
        at android.os.Handler.dispatchMessage(Handler.java:106) 
        at android.os.Looper.loopOnce(Looper.java:201) 
        at android.os.Looper.loop(Looper.java:288) 
        at android.app.ActivityThread.main(ActivityThread.java:7839) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003) 

I don't understand why I am getting such an error because I have made a zero argument constructor and I need it to be used in another class.

Delete:

public Log (ArrayList<logsRow> logs){
        this.logs = logs;
    }

Never implement a constructor on a subclass of AppCompatActivity .

Also, delete:

TimeTable timeTable = new TimeTable();

Never create an instance of a subclass of AppCompatActivity . The system creates instances when that activity should be shown, such as in response to a startActivity() call.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM