findViewById throws null when called through an object - java

I have a function in main.java that uses some UI elements like spinner to textview.
public void updateNearByPeople() {
reportEventPeopleAroundSpinner = (Spinner) findViewById(R.id.peopleAround);
…
}
When I call this function from within class, it works fine.
But when I call this function from another class2.java through an object findViewById throws java.lang.NullPointerException
If I make the function and all variables in it static than it also works fine while calling from class2.java but it doesn’t work with object calls.
How can I solve this and made of object aware of the context?
In main.java:
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_view);
mainAppContext = this;
Main mainObj=new Main();
gMapObj.initiateMap(mainAppContext,mainObj, mapFrag);
}
In class2.java:
public boolean initiateMap(Context appContext, Main mainObj, MapFragment mapFrag) {
mainAppContext = appContext;
mainAppObject = mainObj;
…
mainAppObject.updateNearByPeople();
}

Main mainObj=new Main();
you can't do that. The activity needs to go through its lifecycle, to build up its view hierarchy. If you just instantiate it through the new operator, neither its onAttach or onCreate method will be called. It means that you can not access resources and views as well

Related

Using getIdentifier() to Find ID of Image

I am trying to get id of an image by using following code.
public class MovieActivity extends ActionBarActivity {
private Context con;
String name = "test";
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
con = MovieActivity.this;
setContentView(R.layout.activity_movie);
}
public void updateScreen(){
int imageResource = con.getResources().getIdentifier("drawable/" + name , null, con.getPackageName());
}
}
When I run it, I get exception:
java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Resources android.content.Context.getResources()' on a null object reference
I thought the problem was Context so I added con variable which gets context when code runs. I made some researches and tried another methods but I got same exception every time. Can anyone help me?
EDIT: When I use the same code line in MainActivity, it works perfectly. But in another class, it fails.
public class SomeMovie extends MovieActivity { }
public class MainActivity extends ActionBarActivity {
protected void onCreate(Bundle savedInstanceState) {
SomeMovie movie = new SomeMovie();
movie.updateScreen();
}
}
SomeMovie class is child of MovieActivity class. I call the method on that. I debugged the code and noticed that Context is null when code gets into updateScreen() method. Is it wrong to use inheritance on activity classes?
Change
int imageResource = con.getResources().getIdentifier("drawable/" + name , null, con.getPackageName());
to
int imageResource = getResources().getIdentifier("drawable/" + name , null, con.getPackageName());
You are already in an Activity's context, so use it. (No need to use the this keyword to refer to it)
EDIT:
You are not defining a layout for the SomeMovie Activity, so its context is always null.
You have to define the activity's layout in its onCreate method :
public class SomeMovie extends MovieActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.somemoviexml);
...
}
}

FindViewById cannot be referenced from static context

I am trying to access a method, that changes a text field in the UI, of an Activity from another Java file.
In Game.java (normal Java file in the background) I have some static variables that get changed over time. I want the changes in these variables to be reflected in the actual UI. Hence, I am trying to access the method "changeName" in DisplayMessageActivity.java which would reflect the corresponding changes (display_message_activity.xml).
This is the method in DisplayMessageActivity.java that I am trying to call from Game.java
public void changeName() {
TextView text = (TextView) findViewById(R.id.petname);
text.setText("" + Game.name);
}
To call DisplayMessageActivity.changeName() from Game.java, I have to change it to a static method.
public static void changeName() {
TextView text = (TextView) findViewById(R.id.petname);
text.setText("" + Game.name);
}
But doing that gives me an error "non-static method cannot be accessed from static context" for "findViewByID".
I even tried making an instance of DisplayMessageActivity.java in Game.java to access the "changeName" method without making it static. However that throws a nullPointerException at TextView text = (TextView) findViewById(R.id.petname);
How can I resolve this issue?
Create a static reference to DisplayMessageActivity in itself and initialize it in the onCreate().
public class DisplayMessageActivity {
DisplayMessageActivity instance;
#Override
public void onCreate() {
...
instance = this;
...
}
}
Then from Game.java you can access the non-static method using:
DisplayMessageActivity.instance.changeName();
EDIT: Btw, your NPE is being thrown because you created a new instance of DisplayMessageActivity which is not the one you are actually using.

In Android, how do you call a parent function with View references in it?

Here is the parent class:
public class void ParentClass () extends Activity {
private ListView _listView;
#Override
protected onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_parent);
_listView = (ListView) getViewById(R.id.list_view);
ChildClass cc = new ChildClass();
}
protected void SetScroll() {
try {
_listView.setFastScrollEnabled(false);
} catch (Exception e) {
e.printStackTrace();
}
}
Here is the child class:
private void ChildClass extends ParentClass () {
public ChildClass() {
SetScroll();
}
}
Forgive me with regards to the syntax as I'm typing this from memory. The problem with these classes is that the SetScroll function called from the CallParent function does not work because it is unable to find the right _listView reference (it becomes null). What should I do to make it work correctly? Bear in mind that this is just an example.
But the view is getting null is because you are extending an activity class and before using its view you need to call the onCreate and set the view (if child activity needs new one). But for that you will have to follow the complete flow of the lifecycle. This will help you in extending an activity class. android how to create my own Activity and extend it?
Call parent class activity like this (Just for info). With your code it wont work. You need to correct your code first. See the link I have posted.
super.SetScroll();

How to call non static method from main class

I just ran into this problem while coding android. If I have a non-static method (It has to be non-static for the code inside to work) in my main class, how am i supposed to call it from within another class, because obviously I can't create another instance of my main class without starting a new instance of the program?
public class MainActivity extends FragmentActivity {
public static String starttime = "";
public static String startdate = "";
public static String endtime = "";
public static String enddate = "";
public static boolean start = false;
}
public void setDateText() {
EditText TextStart = (EditText)findViewById(R.id.txt_start);
TextStart.setText(startdate + " at " + starttime, TextView.BufferType.NORMAL);
EditText TextEnd = (EditText)findViewById(R.id.txt_end);
TextEnd.setText(enddate + " at " + endtime, TextView.BufferType.NORMAL);
}
Any help on how to call the setDateText() method from another class?
Thanks in advance
Normally you can't call a non static method from a static type, so you would do:
MainActivity m = new MainActivity(); // No constructor needed in class def.
m.setDateText();
But, when the program starts, you're not giving your JVM anything to call at the start, so you need to add:
#Override
//the function called when activity is created
public void onCreate(Bundle savedInstanceState) {
//call the create fct. Of the base class
super.onCreate(savedInstanceState);
//load the layout specified in the layout.xml
setContentView(R.layout.main);
MainActivity m = new MainActivity();
m.setDateText();
}
This will be called when the activity is created.
Go to Android - A beginner's guide for more information.
Also watch your syntax, your method def is outside of your class def.
Without knowing which other class is trying to access the MainActivity instance, you will need to pass a reference of this instance to your other objects, probably by passing this into a constructor or method.
For example
public class MainActivity extends FragmentActivity {
public void someMethod() {
SomeClass someClass = new SomeClass(this); // pass this for callbacks
// ~ more
}
}
where SomeClass is a class where you need to call the MainActivity's setDateText method.
I am trying to understand the need for you to call the function from another activity. Your main activity is anyway not on the foreground, so if you call this function from there, date will not be shown. Once you finish the 2nd activity and you will be back to MainActivity, then only you need this function to be called.
If that is so, then you can use startActivityForResult() to start 2nd activity, and then pass the date information back to MainActivity through onActivityResult(). You can call this function in MainActivity itself.
If you have to invoke setDate() at the activity's launch, you can pass the date in the Intent when you launch the activity and pull the date in MainActivity's onCreate method.
If you have to invoke setDate() at a different time other than launch, you can send a broadcast from other activity/component and make MainActivity listen to the Broadcast and pull the date from the intent's data.

Android: Referring to a string resource when defining a log name

In my Android app, I want to use a single variable for the log name in multiple files. At the moment, I'm specifying it separately in each file, e.g.
public final String LOG_NAME = "LogName";
Log.d(LOG_NAME, "Logged output);
I've tried this:
public final String LOG_NAME = (String) getText(R.string.app_name_nospaces);
And while this works in generally most of my files, Eclipse complains about one of them:
The method getText(int) is undefined
for the type DatabaseManager
I've made sure I'm definitely importing android.content.Context in that file. If I tell it exactly where to find getText:
Multiple markers at this line
- Cannot make a static reference to the non-static method getText(int)
from the type Context
- The method getText(int) is undefined for the type DatabaseManager
I'm sure I've committed a glaringly obvious n00b error, but I just can't see it! Thanks for all help: if any other code snippets would help, let me know.
That's because getText is a method of Context. It does not matter if you import the Context class; what matters is that you invoke that method from a Context (for instance, the Activity class is a Context (it inherits Context)).
In that case, what I'd recommend, is creating a Application class that returns the context you want. Here I explain how to do it. After that you can do something like:
public final String LOG_NAME = (String) App.getContext().getText(R.string.app_name_nospaces);
Depending on what sort of 'files' you are using, you can define a TAG that is used.
For example, when I create an app, I like to create a base class for my Activity classes...
Suppose my app is called 'Wibble', and my package is com.mydomain.Wibble...I create my base Activity like so...
package com.mydomain.Wibble
public class WibbleActivity extends Activity {
final protected String TAG = this.getClass().getName();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// I'll explain how this next line works later
android.util.Log.d(TAG, "Entered onCreate()...");
}
}
Now suppose I derive an activity as follows...
package com.mydomain.Wibble
public class SomeActivity extends WibbleActivity {
#Override
protexted void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Don't Log "Entered onCreate()..." - WibbleActivity does it for me
android.util.Log.d(TAG, "SomeText");
}
}
Then I derive another Activity...
package com.mydomain.Wibble
public class SomeOtherActivity extends WibbleActivity {
#Override
protexted void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Don't Log "Entered onCreate()..." - WibbleActivity does it for me
android.util.Log.d(TAG, "SomeOtherText");
}
When onCreate() is called for SomeActivity, the output will be...
com.mydomain.Wibble.SomeActivity Entered onCreate()...
com.mydomain.Wibble.SomeActivity SomeText
...when onCreate() is called for SomeOtherActivity however, the output will be...
com.mydomain.Wibble.SomeOtherActivity Entered onCreate()...
com.mydomain.Wibble.SomeOtherActivity SomeOtherText
Neither activity needs to know specifics through an explicit string and the package name is prefixed. Obviously it will only work in certain situations but I find it useful.

Categories