Jenni Jenni - 2 months ago 15
Android Question

FATAL EXCEPTION: main ; OOP ; RuntimeException in JAVA

I started to learn code and java.The submitted project consists of a single .java file, titled ReportCard.java. And i dont want a layout.xml file. I want create just a class. I didnt understand where is my mistake. Thank you very much your help :)

package com.example.android.reportcard; public class ReportCard {
/**
* Create a string to store school name.
*/
private String mSchoolName;

/**
* Create a string to store teacher name.
*/
private String mTeacherName;

/**
* Create a string to store year.
*/
private String mYear;

/**
* Create a string to store student name.
*/
private String mStudentName;

/**
* Create integer for subject math.
*/
private int mMathGrade;


/**
* Create integer for subject science.
*/
private int mScienceGrade;

/**
* Create integer for subject socail studies.
*/
private int mSocialStudiesGrade;

/**
* Create int to have a sum of the grades.
*/
private int mSum;

/**
* Create a private double to indicate the percentage value of the grade.
*/
private double mPercentage;

/**
* Created to show what the total can be.
*/
public static final double TOTAL = 4.0d;

/**
* Get the school name.
*/

public String getSchoolName() {
return mSchoolName;
}

/**
* Get the teacher name.
*/
public String getTeacherName() {
return mTeacherName;
}

/**
* Get the year name.
*/
public String getYear() {
return mYear;
}

/**
* Get the student name.
*/
public String getStudentName() {
return mStudentName;
}

/**
* Get the math grade.
*
* @return mathGrade
*/
public int getMathGrade() {
return mMathGrade;
}

public void setMathGrade(int mathGrade) {
this.mMathGrade = mathGrade;
}


/**
* Get the science grade.
*
* @return scienceGrade
*/
public int getScienceGrade() {
return mScienceGrade;
}

public void setScienceGrade(int scienceGrade) {
this.mScienceGrade = scienceGrade;
}

/**
* Get the social studies grade.
*
* @return socialStudiesGrade
*/
public int getSocialStudiesGrade() {
return mSocialStudiesGrade;
}

public void setSocialStudiesGrade(int socialStudiesGrade) {
this.mSocialStudiesGrade = socialStudiesGrade;
}

private String setGrade(int math, int science, int socialStudies) {
String grade;
mSum = math + science + socialStudies;
mPercentage = mSum / TOTAL;

if (mPercentage >= 90.0) {
grade = "A";
} else if (mPercentage < 90.0 && mPercentage >= 80.0) {
grade = "B";
} else if (mPercentage < 80.0 && mPercentage >= 70.0) {
grade = "C";
} else if (mPercentage < 70.0 && mPercentage >= 60.0) {
grade = "D";
} else if (mPercentage < 60.0) {
grade = "Fail";
} else {
grade = "error";
}
return grade;
}


/**
* Create new report card object.
*
* @param schoolName
* @param teacherName
* @param year
* @param studentName
* @param mathGrade
* @param scienceGrade
* @param socialStudiesGrade
*/

public ReportCard(String schoolName, String teacherName, String year, String studentName,
int mathGrade, int scienceGrade, int socialStudiesGrade) {
mSchoolName = schoolName;
mTeacherName = teacherName;
mYear = year;
mStudentName = studentName;
this.mMathGrade = mathGrade;
this.mScienceGrade = scienceGrade;
this.mSocialStudiesGrade = socialStudiesGrade;
}

public String toString() {
return "School: " + getSchoolName() + '\n' +
"Student Name: " + getStudentName() + '\n' +
"Teacher Name: " + getTeacherName() + '\n' +
"Year: " + getYear() + '\n' +
"Math Grade: " + mMathGrade + '\n' +
"Science Grade: " + mScienceGrade + '\n' +
"Social Studies Grade: " + mSocialStudiesGrade + '\n' +
"Grade: " + setGrade(mMathGrade, mScienceGrade, mSocialStudiesGrade);
}
}


And the Error:

09-28 19:39:53.508 27731-27731/com.example.android.reportcard E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.android.reportcard, PID: 27731
java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.example.android.reportcard/com.example.android.reportcard.ReportCard}: java.lang.InstantiationException: java.lang.Class<com.example.android.reportcard.ReportCard> has no zero argument constructor
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2327)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.lang.InstantiationException: java.lang.Class<com.example.android.reportcard.ReportCard> has no zero argument constructor
at java.lang.Class.newInstance(Native Method)
at android.app.Instrumentation.newActivity(Instrumentation.java:1067)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2317)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476) 
at android.app.ActivityThread.-wrap11(ActivityThread.java) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:148) 
at android.app.ActivityThread.main(ActivityThread.java:5417) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 

Answer

An Android application is not the same as a console application. An Android application always requires a graphical entry point in the form of a Launching Activity, in order for the platform to know where to start executing code. Think of it as the main method in regular Java applications.

From the Android Activity Documentation:

An activity is a single, focused thing that the user can do. Almost all activities interact with the user, so the Activity class takes care of creating a window for you in which you can place your UI with setContentView(View).

In order to create a ReportClass object and use its declared fields and methods, you will need to declare your application's entry point. To do this, create a new class and call it MyMainActivity.

public class MyMainActivity extends Activity
{


}

Again, paraphrasing from the Android Activity Documentation:

The onCreate(Bundle) method will be implemented by almost all of the classes extending Activity. This method is where you initialize your activity. Most importantly, here you will usually call setContentView(int) with a layout resource defining your UI, and using findViewById(int) to retrieve the widgets in that UI that you need to interact with programmatically.

The next step is to implement the onCreate method mentioned in the docs. Given that you are not going to interact with the user interface, you can simply call setContentView() using an empty layout. Don't pay attention to the Bundle argument, as it will only confuse you for now.

public class MyMainActivity extends Activity
{
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
         super(savedInstanceState);
         setContentView(R.layout.my_empty_layout);
    }
}

You should create the my_empty_layout.xml file in the /res/layout folder, and the you can leave the generated content as is:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="match_parent"
              android:layout_height="match_parent">

</LinearLayout>

The final thing you need to do is specify to the platform which Activity should be the entry point to your application. Even though you have only declared one, you will still need to specify it. This is done in the Android Manifest file, located at /app/manifests. There will already be xml content there, including an <application> </application> tag. Inside this element, add an activity child node (<activity>``</activity>) in which you specify the full path to your declared activity, as well as mark it as your applications entry point using an intent-filter. The activity node should then look something like this:

<activity android:name="path.to.the.activity.MyMainActivity">

     <intent-filter>
          <action android:name="android.intent.action.MAIN"/>
          <category android:name="android.intent.category.LAUNCHER"/>
     </intent-filter>

</activity>

Now you finally have an entry point to your Android application and you can begin creating ReportCard objects and start messing around with them:

public class MyMainActivity extends Activity
{
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
         super(savedInstanceState);
         setContentView(R.layout.my_empty_layout);

         ReportCard myFirstReportCard = new ReportCard("SO College", "Mr. Kooijman", "2016", "aylin", 80, 72, 55);
         int socialStudiesGrade = myFirstReportCard.getSocialStudiesGrade();
    }
}

However, I do strongly suggest that you read up some more on what an Android application is and how one should go about creating one. The question you've posed indicates a great lack of understandning about what the platform is, how and what it enables you do to and how you should be doing it.