An activity that retrieves and displays data from a database failed to instantiate because there is no zero argument constructor - why is it important to include it?
Here is the activity (I'm quite new to this so there will be parts where it could have been executed better...open to suggestions!)
package com.example.createrecipefinal;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
import java.util.List;
public class preview_recipe extends AppCompatActivity {
private DBHelper dbHelper;
private TextView viewRecipeName, viewCountry, viewTime, viewTxtEquipment, viewTxtIngredients, viewTxtMethod, viewPersonalStory;
public preview_recipe(DBHelper dbHelper) {
this.dbHelper = dbHelper;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_preview_recipe);
viewRecipeName = findViewById(R.id.viewRecipeName);
viewCountry = findViewById(R.id.viewCountry);
viewTime = findViewById(R.id.viewTime);
viewTxtEquipment = findViewById(R.id.viewTxtEquipment);
viewTxtMethod = findViewById(R.id.viewTxtMethod);
viewPersonalStory = findViewById(R.id.viewPersonalStory);
viewTxtIngredients = findViewById(R.id.viewTxtIngredients);
DBHelper dbHelper = new DBHelper(preview_recipe.this);
//call read function and array
List<RecipeModel> returnRecipe = dbHelper.readRecipe();
//Setting values into text views
viewRecipeName.setText((CharSequence) returnRecipe.get(1));
viewCountry.setText((CharSequence) returnRecipe.get(2));
viewTxtEquipment.setText((CharSequence) returnRecipe.get(5));
viewTxtIngredients.setText((CharSequence) returnRecipe.get(6));
viewTxtMethod.setText((CharSequence) returnRecipe.get(7));
viewPersonalStory.setText((CharSequence) returnRecipe.get(8));
}
}
2022-04-04 19:37:05.963 14815-14815/com.example.createrecipefinal E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.createrecipefinal, PID: 14815
java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.example.createrecipefinal/com.example.createrecipefinal.preview_recipe}: java.lang.InstantiationException: java.lang.Class<com.example.createrecipefinal.preview_recipe> has no zero argument constructor
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3591)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3842)
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:2252)
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:7842)
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)
The zero argument constructor is required because the android runtime doesn't know how to create the object (DBHelper dbHelper) that your constructor requires.
The dbHelper that your constructor requires as useless anyway (you create a new DBHelper(preview_recipe.this) in onCreate()), so the solution is to remove this useless parameter:
public class preview_recipe extends AppCompatActivity {
private TextView viewRecipeName, viewCountry, viewTime, viewTxtEquipment, viewTxtIngredients, viewTxtMethod, viewPersonalStory;
public preview_recipe() {
}
//... remainder of the code
}
Please also note that in Java (and Android) it is the convention to write class names in CamelCase (like the AppCompatActivity), so your class should be named:
public class PreviewRecipe extends AppCompatActivity {
private TextView viewRecipeName, viewCountry, viewTime, viewTxtEquipment, viewTxtIngredients, viewTxtMethod, viewPersonalStory;
public PreviewRecipe() {
}
//... remainder of the code
}
Related
When using Hilt with Espresso I found that my activity is either not resumed or not destroyed. When I comment out the very first test that launches my activity the second one started to pass. The workaround is to separate each test however this will produce a lot of boiler plate code.
Also I have a custom activity inside the tests that inherits from my main activity.
#RunWith(AndroidJUnit4.class)
#HiltAndroidTest
public class MainActivityTest {
// ... initilisation & mocks
#Before
public void setUp() {
MockitoAnnotations.initMocks(this);
hiltAndroidRule.inject();
context = getInstrumentation().getTargetContext();
// ... other initialisation and setup
}
// Helper classes and functions
#AndroidEntryPoint
public class ModifiedMainActivity extends MainActivity {
// ... custom activity implementations
}
// Factory
private SingleActivityFactory<MainActivity> activityFactory = new SingleActivityFactory<MainActivity>(MainActivity.class) {
#Override
protected MainActivity create(Intent intent) {
ModifiedMainActivity mainActivity = new ModifiedMainActivity();
// other custom activity configuration & setup
return mainActivity;
}
}
#After
public void tearDown() {
// ... other code to tear down some stubs
}
}
Any ideas?
I can provide some code but other is under NDA.
My rules:
#Rule(order = 0)
public HiltAndroidRule hiltAndroidRule = new HiltAndroidRule(this);
#Rule(order = 1)
public ActivityTestRule<MainActivity> mainActivityRule = new ActivityTestRule<>(activityFactory, true, false);
Test example:
#Test
public void test_report_system_back_button_pressed_when_closing_main_activity() {
Intent intent = new Intent(Intent.ACTION_MAIN);
final MainActivity mainActivity = mainActivityRule.launchActivity(intent);
getInstrumentation().runOnMainSync(mainActivity::onBackPressed);
verify(mockedHelper, times(1)).reportEvent(eq(Codes.SYSTEM_BACK_PRESSED), eq("SystemBackPressed"), nullable(Map.class));
}
Exception:
java.lang.RuntimeException: No activities found. Did you forget to launch the activity by calling getActivity() or startActivitySync or similar?
at androidx.test.espresso.base.RootViewPicker.waitForAtLeastOneActivityToBeResumed(RootViewPicker.java:176)
at androidx.test.espresso.base.RootViewPicker.get(RootViewPicker.java:88)
at androidx.test.espresso.ViewInteractionModule.provideRootView(ViewInteractionModule.java:77)
at androidx.test.espresso.ViewInteractionModule_ProvideRootViewFactory.provideRootView(ViewInteractionModule_ProvideRootViewFactory.java:37)
at androidx.test.espresso.ViewInteractionModule_ProvideRootViewFactory.get(ViewInteractionModule_ProvideRootViewFactory.java:27)
at androidx.test.espresso.ViewInteractionModule_ProvideRootViewFactory.get(ViewInteractionModule_ProvideRootViewFactory.java:10)
at androidx.test.espresso.base.ViewFinderImpl.getView(ViewFinderImpl.java:63)
at androidx.test.espresso.ViewInteraction$2.call(ViewInteraction.java:280)
at androidx.test.espresso.ViewInteraction$2.call(ViewInteraction.java:272)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
Please help me guys I'm stuck on this problem for over a week.
I'm working on an app which involves groovy. The app simply creates a pdf document with some information.
The part where the pdf is created is written in groovy. I wrote a small groovy library which takes some information and create a pdf document using pdfbox. This library was developed in IntelliJ IDEA and it works perfectly.
Now, the problem occurs when I try to integrate this groovy library with my android application. I managed to build an artifact of the groovy library and even import it to the android studio under libs folder, but when I try to run the main function of groovy library, the app crashes with a MissingPropertyException:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.silverfix.groovytestapp, PID: 8030
groovy.lang.MissingPropertyException: No such property: EMPTY_DOC for class: app.Constants$Paths
at groovy.lang.MetaClassImpl.invokeStaticMissingProperty(MetaClassImpl.java:1004)
at groovy.lang.MetaClassImpl.getProperty(MetaClassImpl.java:1859)
at groovy.lang.MetaClassImpl.getProperty(MetaClassImpl.java:1835)
at groovy.lang.MetaClassImpl.getProperty(MetaClassImpl.java:3735)
at org.codehaus.groovy.runtime.callsite.ClassMetaClassGetPropertySite.getProperty(ClassMetaClassGetPropertySite.java:51)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callGetProperty(AbstractCallSite.java:296)
at app.MainClass.initialize(MainClass.groovy:41)
at app.MainClass.main(MainClass.groovy:32)
at com.silverfix.groovytestapp.MainActivity$1.onClick(MainActivity.java:24)
at android.view.View.performClick(View.java:4780)
at android.view.View$PerformClick.run(View.java:19866)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
Code for main class of the groovy library:
package app
import app.components.Evaluator
import app.components.FieldRenamer
import app.components.FormMetaHolder
import app.components.FieldPopulater
import app.components.entities.DGObject
import org.apache.pdfbox.cos.COSDictionary
import org.apache.pdfbox.cos.COSName
import org.apache.pdfbox.pdmodel.PDDocument
import org.apache.pdfbox.pdmodel.PDDocumentCatalog
import org.apache.pdfbox.pdmodel.PDPage
import org.apache.pdfbox.pdmodel.PDResources
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationWidget
import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm
import org.apache.pdfbox.pdmodel.interactive.form.PDField
/**
* Created by David on 26/09/2016.
*/
class MainClass {
static PDDocument document = new PDDocument()
static void main(args) {
initialize()
initiateData()
initiatePdf()
populateData()
saveDocuemnt()
}
// Initialize the document's meta data
static void initialize() {
InputStream inputStream = MainClass.class.getClassLoader().getResourceAsStream("$Constants.Paths.EMPTY_DOC")
PDDocument tempDoc = new PDDocument().load(inputStream)
}
static void initiatePdf() {
...
}
static void initiateData() {
...
}
static void populateData() {
...
}
static void saveDocuemnt() {
...
}
}
Code for Constants class:
package app
/**
* Created by David on 09/10/2016.
*/
class Constants {
// Paths
public static class Paths {
public static final String RESULT_FILE = "intellijPDF.pdf"
public static final String EMPTY_DOC = "dgc_empty.pdf"
public static final String IATA_DOC = "dgc_iata.pdf"
public static final String SILVER_DOC = "dgc_silverfix.pdf"
}
}
And this is the MainActivity:
package com.silverfix.groovytestapp;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import app.MainClass;
public class MainActivity extends AppCompatActivity {
private Button button;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = (Button) findViewById(R.id.create_doc);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
MainClass.main(null);
}
});
}
}
Image of the Project hierarchy
add #CompileStatic try again.
#CompileStatic
public class MainClass {
To use Groovy library in Android project it is necessary to configure Groovy support for Android: https://github.com/groovy/groovy-android-gradle-plugin
After applying Groovy plugin to Android you can add your library as follows (assuming it is in libs directory):
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs') {
exclude group: 'org.codehaus.groovy'
}
compile 'org.codehaus.groovy:groovy:2.4.12:grooid'
...
}
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 6 years ago.
Problem: (All info below) I've set up the app to get text from EditText component and add it into a LinkedList once the button is pressed.
Tests: Testing for getText.toString() was successful (so u_in had a usable string) and I also tried to implement a simple array within my MainActivity and perform the same function which worked perfectly. Although I keep getting a NullPointerException with the database class and LinkedList.
I've also tried adding a null check in the OnClick anonymous method, but still got the same error.
Testing using physical device and running Android Studio 2.1
Main class:
public class MainActivity extends AppCompatActivity {
public Data_base db;
public String u_in;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
check_button();
}
public void check_button() {
Button add_button = (Button) findViewById(R.id.button);
final EditText etext = (EditText) findViewById(R.id.editText);
add_button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v){
u_in = etext.getText().toString();
db.add(u_in,0);
}
});
}
Input class(Initializes information):
public class Input {
public String input;
public int age;
public Input (String input, int age) {
this.input = input;
this.age = age;
}
}
Database class (where I have my linkedlist and methods to manipulate it):
public class Data_base {
public LinkedList<Input> user_in = new LinkedList<>();
public void add(String in, int age) {
user_in.add(new Input(in, age));
}
public LinkedList<Input> getList() {
return user_in;
}
}
Error:
05-02 22:51:59.202 2813-2813/com.example.user.test_app E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.user.test_app, PID: 2813
java.lang.NullPointerException: Attempt to invoke virtual method 'void com.example.user.test_app.Data_base.add(java.lang.String, int)' on a null object reference
at com.example.user.test_app.MainActivity$1.onClick(MainActivity.java:33)
at android.view.View.performClick(View.java:5155)
at android.view.View$PerformClick.run(View.java:20747)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:5832)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)
In your MainActivity you're using db.add without instantiating db first.
Edit Addressing Comment:
Not sure exactly what you're doing with the age variable, but generally there are some ways to programatically get the same variable from an entire collection:
1) Get the value while iterating over the original collection:
//Somewhere in your business logic:
for(Input i : db) {
String text = i.getInput(); //Your class should have getters and setters
//Do something with the text variable
}
2) Make a List<String> using a static method in your Input class:
public static List<Input> stringsFromInputs(List<Input> inputs) {
List<String> ret = new ArrayList<String>();
for(Input i : inputs)
ret.add(i.getInput()); //Again, your class should have getters/setters
return ret;
}
3) If you're not going to use such a static method often, then perform this logic where needed in the code itself (which you seem to want to avoid).
Hope this helps some.
In onCreate before calling check_button() add:
db = new Data_base();
Create Data_base object first in MainActivity the try to do operation with add method
This is the class of which I want to test EditText. But when I try to assign that EditText field in the Test clas it shows an null pointer exception. I have omitted other use less code for the problem
public class LogInActivity extends ActionBarActivity {
private Button signUpButton;
private Button logInButton;
private Intent signUpChoiceIntent;
private Intent homeActivityIntent;
private String username;
private String password;
private EditText usernameTextField;
private EditText passwordTextField;
private HumLogController humLogController;
private String error;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_log_in);
humLogController = (HumLogController) getIntent().getSerializableExtra("controllerObject");
setIntentAndButton();
}
private void setAndCheckFields(){
/** I want to test this, (view with id:- logInUsernameField ) which is working fine in practice, but not passing the test. When I try to call the same id in Test class with instance of this class, it gives a null pointer exception. */
usernameTextField = (EditText) findViewById(R.id.logInUsernameField);
}
This is the test class where I am testing for the EditText field, but giving a null pointer exception
public class LogInActivityInstrumentTest extends InstrumentationTestCase{
LogInActivity logInActivity;
#Override
protected void setUp() throws Exception{
super.setUp();
logInActivity = new LogInActivity();
}
public void testUsernameTextViewNullTest(){
// The line below is line 23. Which is giving null pointer Exception...?
EditText text = (EditText) logInActivity.findViewById(R.id.logInUsernameField);
assertNotNull(text);
}
#Override
protected void tearDown() throws Exception{
super.tearDown();
}
}
The log cat is given below.
java.lang.NullPointerException
at android.app.Activity.findViewById(Activity.java:1853)
at com.example.praduman.humlog.tests.LogInActivityInstrumentTest.testUsernameTextViewNullTest(LogInActivityInstrumentTest.java:23)
at java.lang.reflect.Method.invokeNative(Native Method)
at android.test.InstrumentationTestCase.runMethod(InstrumentationTestCase.java:214)
at android.test.InstrumentationTestCase.runTest(InstrumentationTestCase.java:199)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:191)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:176)
at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:554)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1701)
You cannot create an Activity simply calling its constructor as you did. In a test context, you need some kind of instrumentation to allow everything to work properly. Try to take a look at Espresso (for in device tests) or even Robolectric (for JVM tests).
You can not create an instance of your activity using the constructor like ou have done in the above code.
Try changing the following in your LogInActivityInstrumentTest
public class LogInActivityInstrumentTest extends InstrumentationTestCase<LogInActivity>{
public LogInActivityInstrumentTest() {
super(LogInActivity.class);
}
#Override
protected void setUp() throws Exception{
super.setUp();
logInActivity = new getActivity();
}
}
The documentation for running tests can be found here, on developer.android.com.
In the code you have posted - simple creating the Activty using its constructor does not run it through the lifecycle that an activity expects. The reason for your NullPointerException is the fact that onCreate has not been run, meaning that you are trying to look up a view before you have called setContentView(), therefore, the view really is null.
I have an exception that is thrown after the app has been sitting idle for awhile. It seems to always happen when my app is trying to reference my singleton typeface class.
My singleton class (TypefaceSingleton.java) is used to reference the Roboto fonts from a single source. This is a scaled down version of the actual file. I have labeled the line from the stack trace.
TypefaceSingleton.java class
package com.steve.demo;
import android.content.Context;
import android.graphics.Typeface;
import android.view.View;
public class TypefaceSingleton {
private static Context mContext;
public static void initialize(Context context) {
mContext = context;
}
private static Typeface robotoCondensedBoldItalic;
public static Typeface getRobotoCondensedBoldItalic() {
if (robotoCondensedBoldItalic == null) {
// (TypefaceSingleton.java:111) is below
robotoCondensedBoldItalic = Typeface.createFromAsset(mContext.getAssets(), "fonts/Roboto/RobotoCondensed-BoldItalic.ttf");
}
return robotoCondensedBoldItalic;
}
private static TypefaceSingleton mInstance;
public static TypefaceSingleton getInstance() {
if (mContext == null) {
throw new IllegalArgumentException("This class must be initialized before");
}
if (mInstance == null) {
mInstance = new TypefaceSingleton();
}
return mInstance;
}
private TypefaceSingleton() {
// Todo here
}
}
I initialize the singleton class only once. I have a splashscreen activity that performs the initialization.
SplashScreenActivity.java
// Perform Initialization
TypefaceSingleton.initialize(mContext.getApplicationContext());
TypefaceSingleton.getInstance();
The exception thrown is indicating a null pointer reference to TypefaceSingleton.getRobotoCondensedBoldItalic.
From the Developers Console
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.steve.demo/com.steve.demo.RoutesActivity}: java.lang.NullPointerException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2334)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2392)
at android.app.ActivityThread.access$900(ActivityThread.java:169)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1280)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:146)
at android.app.ActivityThread.main(ActivityThread.java:5487)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1283)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at com.steve.demo.TypefaceSingleton.getRobotoCondensedBoldItalic(TypefaceSingleton.java:111)
at com.steve.demo.RoutesActivity.setCustomActionBarTitle(RoutesActivity.java:130)
at com.steve.demo.RoutesActivity.onCreate(RoutesActivity.java:86)
at android.app.Activity.performCreate(Activity.java:5451)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1093)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2298)
... 11 more
I am sure the issue have to with the java is handling memory (ie, garbage collection?) but I not sure how to resolve.
Thanks in advance.
Steve