Android/Java - NullPointerException - android

public class Excuses extends ActionBarActivity {
// openings
private String[] openings = {
getString(R.string.opening_1),
getString(R.string.opening_2),
getString(R.string.opening_3),
getString(R.string.opening_4),
getString(R.string.opening_5),
getString(R.string.opening_6),
getString(R.string.opening_7),
getString(R.string.opening_8),
getString(R.string.opening_9),
getString(R.string.opening_10),
getString(R.string.opening_11),
getString(R.string.opening_12),
getString(R.string.opening_13),
getString(R.string.opening_14),
getString(R.string.opening_15),
getString(R.string.opening_16),
getString(R.string.opening_17)
};
When ran, this error pops up:
Caused by: java.lang.NullPointerException
at android.content.ContextWrapper.getResources(ContextWrapper.java:89)
at android.view.ContextThemeWrapper.getResources(ContextThemeWrapper.java:79)
at android.content.Context.getString(Context.java:352)
at com.aczylsapp.com.excusegenerator.Excuses.<init>(Excuses.java:12)
This line gives me the NullPointerException:
private String[] openings = {
and, I have no idea why :/
I have already looked at other posts, but they do not help me.
If someone could help me out, I would be greatful.

The problem is that the Activity was not fully constructed, based on Activity Lifecycle and you cannot access the Resources properly.
You must move this assignment to inside onCreate method. Like:
public class Excuses extends ActionBarActivity {
// openings, will be initialize in onCreate method
private String[] openings;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initializeOpenings();
// Your initialization code
}
public void initializeOpenings() {
openings = new String[] {
getString(R.string.opening_1),
getString(R.string.opening_2),
getString(R.string.opening_3),
getString(R.string.opening_4),
getString(R.string.opening_5),
getString(R.string.opening_6),
getString(R.string.opening_7),
getString(R.string.opening_8),
getString(R.string.opening_9),
getString(R.string.opening_10),
getString(R.string.opening_11),
getString(R.string.opening_12),
getString(R.string.opening_13),
getString(R.string.opening_14),
getString(R.string.opening_15),
getString(R.string.opening_16),
getString(R.string.opening_17)
};
}
}
But there is a better way to do this!
Create an String Array in your resource, like:
<string-array name="openings">
<item>#string/opening_1</item>
<!-- Declare all your items here -->
<item>#string/opening_17</item>
</string-array>
And access then with getStringArray(int resId):
public class Excuses extends ActionBarActivity {
// openings, will be initialize in onCreate method
private String[] openings;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initializeOpenings();
// Your initialization code
}
public void initializeOpenings() {
openings = getResources().getStringArray(R.array.openings);
}
}

Null Pointer exception means that the objects you are trying to put into your array are empty or dont exist.
In your case, this likely means that getString(R.string.opening_1) is returning null.
I suspect that the issue lies with the parameter you are putting in your getString() method. If I were you, I'd take a good look at your getString() and check that getString(R.string.opening_1) is returning the String you want it to.
Based on the Android Documentation for getString(), you need to make sure that the "Resource id for the string" can be found.

Related

OnClickListener: Why I cannot access public methods of the object in ArrayAdapter? Any workaround?

Greetings from a greenhorn. This question is a bit long, sorry for that.
My android app loads xml to the listview, then after clicking any listview item I want to pass some information to second activity. With
piesneLVdata.getItemAtPosition(position).toString()
And here is my object:
public class Piesen {
private String nazov_piesne;
private String text_piesne;
}
+ some get and set methods and override of toString...
I can access the first property of the object and I can use it in my second activity. I guess it is because I have overriden the method inside my object definition:
#Override
public String toString() {
return nazov_piesne;
}
However I am not able to access the second property of my object. Tried this:
piesneLVdata.getItemAtPosition(position).getTextPiesne()
but getTextPiesne() seems not to be reachable - then why the "toString()" is reachable? The information is there, I can access it outside of the onClickListener with this formulation:
zoznamPiesni.get(position).getText_piesne().toString();
but when I try to use it in onClickListener I get the error:
Error:(64, 45) error: local variable zoznamPiesni is accessed from within inner class; needs to be declared final
But then, when I declare it final I cannot load a xml file into it. I feel officialy stucked in there. Maybe I should redesign the toString() method to contain an array of both properties of my object. Could you please point me to the correct direction? Thanks a lot in advance.
To be specific, here is my activity:
public class ListActivity extends AppCompatActivity {
ListView piesneLVdata;
Toolbar nadpis;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list);
nadpis = (Toolbar) findViewById(R.id.toolbar);
nadpis.setTitle(getResources().getString(R.string.nadpis));
piesneLVdata = (ListView) findViewById(R.id.piesneLVgui);
List<Piesen> zoznamPiesni = null;
try {
XMLPullParserHandler parser = new XMLPullParserHandler();
zoznamPiesni = parser.parse(getAssets().open("piesne.xml"));
//sort the collection piesne alphabetically a-z
Collections.sort(zoznamPiesni, new Comparator<Piesen>() {
#Override
public int compare(Piesen a1, Piesen a2) {
// String implements Comparable
return (a1.getNazov_piesne().toString()).compareTo(a2.getNazov_piesne().toString());
}
});
ArrayAdapter<Piesen> adapter = new ArrayAdapter<Piesen>(this,android.R.layout.simple_list_item_1,zoznamPiesni);
piesneLVdata.setAdapter(adapter);
}catch (IOException e) {
e.printStackTrace();
}
piesneLVdata.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent slovaIntent = new Intent(ListActivity.this, SongActivity.class);
Bundle balik = new Bundle();
balik.putString("NAZOV", piesneLVdata.getItemAtPosition(position).toString());
//balik.putString("TEXT", piesneLVdata.getItemAtPosition(position).getTextPiesne());
// balik.putString("TEXT", zoznamPiesni.get(position).getText_piesne().toString());
slovaIntent.putExtras(balik);
startActivity(slovaIntent);
}
});
}
The problem is that
piesneLVdata.getItemAtPosition(position)
return a Piesen treated as an Object. Object has toString method, so yo ucan call that method, that is overriden by the Piesen.class.
What you need is simply cast your object to a Piesed like follows:
((Piesen)piesneLVdata.getItemAtPosition(position)).getTextPiesne()

Passing an EditText Object and EditText.setText() throw Exception

I have an Activity the implements the following functions:
public class SettingsActivity extends Activity {
public void setText(EditText txtBox,String strText){
txtBox.setText(strText);
}
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.settings);
EditText txtEdit = (EditText)findViewById(R.id.txtEdit);
setText(txtEdit,"String");
...
}
So I am trying to pass an EditText Object to the setText Function and then calling the txtBox.setText() function. But this throws the following exception:
android.content.res.Resources$NotFoundException: String resource ID #0x0
However, when calling the txtEdit.setText() function within onCreate() works perfectly fine.
Edit: The function setText was a simplification, I was actually passing an object a of custom class a then called txtBox.setText(object.value), which ( by mistake) was actually an Integer, not a String. Passing a String fixed the error. I am sorry for the inconvenience.
I just realized that, in fact I did not pass a String Parameter. Like #Lubos Horacek described the exception is thrown when you are passing an int to setText. Converting the parameter fixed the error.
May be your id doesn't exist in layout file

Android create static ArrayList

im trying to remove values from an arrayList im my android app, but they keep re-appearing.
My arrayList is in a separate class,
in my Main Activty I create an instance of that class and remove a value from the array.
I exit the Main Activity and return the value re-appears.
My Question is how can I can some kind of static instance of the array class???
//ArrayClass
public class ArrayClass {
public final static ArrayList<String> words = new ArrayList<String>();
public ArrayClass() {
words.add("WORD");
words.add("WORD");
words.add("WORD");
}
//Main Class
ArrayClass wordc = new ArrayClass();
#Override
protected void onCreate(Bundle savedInstanceState) {
wordc.removeWord(0);
}
Orest is correct you do want a singleton pattern, but remember when you access the class's methods you always need to use the getInstance() method.
For example a method within the Class:
public String getWord(index i) {
.......
}
Should be called statically as follows
ArrayClass.getInstance().getWord(i);
NOT like this
wordc.getWord(i);
This guarantees that there is one and only one instance (thus the singleton)
I might be confused on what you are doing but to access the static Array you don't want to create an instance of the class. Everytime you do that you are running the constructor which, in the example code, populates your static Array each time with 3 values.
I don't see exactly what you are trying to accomplish so maybe you could explain that a little better but I'm guessing this really isn't what you want your constructor doing. I think you want to access the Array itself statically
//Main Class
ArrayClass wordc = new ArrayClass();
#Override
protected void onCreate(Bundle savedInstanceState) {
wordc.removeWord(0); //don't need this
ArrayClass.words.remove(0); // would remove the element at index 0
}
But this still wouldn't solve your problem. You need a method inside your ArrayClass class that adds items to your Array. Doing it in your constructor will add these items each time you create a new instance of your class.
If this doesn't answer your question then maybe you can explain your assignment a little better.
Have you tried the Singleton patter? You will have one static reference of ArrayClass and it's internal state won't be violated by activity lifecycle.
public class ArrayClass {
private static ArrayClass instance;
public static ArrayClass getInstance() {
if(instance == null) instance = new ArrayClass();
return instance;
}
//...rest goes as is.

How to use global class variables in android

Hi I am doing one app here. I'm using global class varibles. It's working well, but if I'm using more globalclass variables I'm getting memory exceptions some times.
I tried this:
public class SecondClass extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.second);
TextView tv = (TextView)findViewById(R.id.tv);
tv.setText("Global String : " + GlobalClass.myVal);
}
}
class GlobalClass extends Application {
static String myVal;
}
Is this correct or not?
First thing, you dont need Static Variable to declare global variable in Application Class,
so Change your code to:
class GlobalClass extends Application {
public String myVal;
}
then whereever you need to access this data, get Application object by:
GlobalClass global=(GlobalClass)context.getApplication();
global.myVal="anything";
You can use like this
public class GlobalVar {
public int getMyVar() {
return myVar;
}
public void setMyVar(int myVar) {
this.myVar = myVar;
}
private int myVar = 0;
private static GlobalVar instance;
static {
instance = new GlobalVar();
}
private GlobalVar() {
}
public static GlobalVar getInstance() {
return GlobalVar.instance;
}
}
then you can call like
GlobalVar.getInstance().setMyVar(int);
You can also use Global Variable Activity class wise. As for example
public class SecondClass extends Activity {
String S1,S2,S3;
EditText edt1,Edt2,Edt3;
Button btn1,btn2,btn3;
//like this wat Declare all variable you want to use in your Present Activity Class
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.second);
edt1= (EditText)findViewById(R.id.tv);
}
}
Take a look at the post Singletons vs. Application Context in Android?
There are a lot of discussion about Singletons vs Application objects in the forum.
I'm personally inclined to Application object with properties. If you dont want to keep in memory a lot of objects use a LruCache (there is a pre v11 implementation in the compatibility package) to low your memory requirements.
Take into account you will eat the same amount of memory using Singletons than using the Application object, all objects will be keep in memory until you free them (remove any refrence to them and let the GC purge them from memory).

Another "Cannot make static reference..." Question

I am trying to write an Activity that has some views, a fillView() method that sets the views (which is not static because it must utilize getContentResolver), and a static method that makes a random choice from a cursor and then runs the fillView() method.
I had problems with this due to fillView not being static and pickRandom being static, so I tried to initialzize an instance of the class, but now it crashes on the line instance.fillView();
Sample code below. Any help would be appreciated. Perhaps there is a much easier way to accomplish what I am trying to do.
Thanks,
Josh
public class myView extends Activity implements OnClickListener {
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.myView);
fillView();
}
public void fillView(){
//creates views, runs cursor and applies results to the view created
}
public static void pickRandom() {
// runs cursor, picks random entry, next I want to apply the result to
// view, so I run...
myView v = new myView();
v.fillView();
}
Make a static instance variable and set in in oncreate:
private static myView instance;
oncreate()
instance = this;
static pickrandom()
instance.fillView();
in your pickRandom you try to create new instance of your class. Instead of this you should do the following:
this.fillView();
I don't see any purpose you have your pickRandom static.
If, however, you need it for some reason you can pass a reference to your view like this:
public static void pickRandom(myView v) {
// runs cursor, picks random entry, next I want to apply the result to
// view, so I run...
v.fillView();
}

Categories

Resources