Android: error when using int array passed into class - android

I am passing an int array from one class to another but am getting an error when I try to access values from it. I have no idea why, hopefully someone can enlighten me?
Here's the first class that calls the second:
public class ConvertToGrid extends Activity{
DrawGrid v;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...code...
int[] binArray = {Color.RED, Color.WHITE, Color.YELLOW, ...};
v = new DrawGrid(this, binArray);
setContentView(v);
}}
This calls my DrawGrid View:
public class DrawGrid extends View{
private int[] binary;
public DrawGrid(Context context) {
super(context);
}
public DrawGrid(Context context, int[] inBinary) {
super(context);
binary = inBinary.clone();
}
int sq00c = binary[0];
...etc}
What am I doing wrong such that it cannot access this int array called binary? If I move the int array into DrawGrid it accesses the cells without any trouble, but passing it through with my construct seems to make it inaccessible. In case anyone asks, I can't just define the array in DrawGrid as it is defined by the code in ConvertGrid.
Perhaps I am going about this in the wrong way and there is a better way to pass the int array? Thanks
Edit:
LogCat:
E/AndroidRuntime(12035): FATAL EXCEPTION: main
E/AndroidRuntime(12035): java.lang.RuntimeException: Unable to start activity ComponentInfo{bras2756.ox.ac.uk.colourgrid/bras2756.ox.ac.uk.colourgrid.ConvertToGrid}: java.lang.NullPointerException

You can't do that because your int sq00c = binary[0]; type statements are outside a method body, and hence get executed before your constructor is called, which makes the binary array empty. So when you try to access data in it, you'll get an ArrayIndexOutOfBounds exception.
Try using:
public class DrawGrid extends View{
private int[] binary;
private int sq00c;
etc....
public DrawGrid(Context context) {
super(context);
}
public DrawGrid(Context context, int[] inBinary) {
super(context);
binary = inBinary;
sq00c = binary[0];
...etc
}
}
I've split the int declaration and the assignment into two. The ints are still declared at the class level, but are only given a value when the constructor is called.

By seeing the exception seems like this is your problem
Clone() create a shallow copy check this link
I think following modification will solve your problem
public DrawGrid(Context context, int[] inBinary) {
super(context);
binary = inBinary; //update to this
}

Related

Android/Java - NullPointerException

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.

Android: getApplicationContext() won't work in View subclass

So i have made a class DrawView which extends View and i want to draw some graph in that class with the points i stored as int array
i made this array like a sort of public variable with the help of How to declare global variables
So when i want to get connected with MyApp in Activity and change my array, i simply use
MyApp appState = ((MyApp)getApplicationContext());
but the problem is that this won't work when i call it in my DrawView.java class.
Any ides how to solve this?
I really don't know why that answer is so up voted as it's not a good solution.
The Application object is to run the Application, not to store data, you can solve this MUCH easier with a simple Singleton object, try this:
public Class MyData{
private int[] data;
private static MyData me;
public int[] getData(){
return data;
}
private MyData(){} // private constructor
public MyData get() {}
if(me==null) me = new MyData();
return me;
}
}
than from any object you can call:
int[] data = MyData.get().getData()
and feel free to expand to more than just a int[] ... put any other object that you want to be globally accessible. But remember, DO NOT KEEP REFERENCES TO THE CONTEXT!

getResources in non-activity class

I've been trying to load a bitmap in a non-activity class but everything I've done so far has failed. I have even tried to send the Context as reference, but this also results in error.
My current situation looks like this:
// Surface class
public class GameScreen extends SurfaceView implements Callback {
TileSet ts;
public GameScreen(Context context, AttributeSet attr) {
// Here I send context as a reference
ts = new TileSet(context, R.drawable.tiles);
}
}
// This is the class I need to get resources
public class TileSet {
public TileSet(Context context, int id) {
Bitmap bmp = BitmapFactory.decodeResource(context.getResources(), id);
}
}
Any ideas?
Have you tried just getting the bitmap in the Activity and then passing that to the constructor of your GameScreen?

Android ListView AdddAll problem

hi i am Using ArrayAdapter in ListView with custom Class object,HERE IS MY CODE
private static class NewsDetailAdapter extends ArrayAdapter<clsNewsItem>
{
private final Activity context;
List<clsNewsItem> newsList = null;
public NewsDetailAdapter(Activity context, ArrayList<clsNewsItem> clsNewsObjects) {
super(context, R.layout.listview_cell, clsNewsObjects);
this.context = context;
this.newsList = clsNewsObjects;
}
public void clear()
{
newsList.clear();
}
while i am working with this code AdapterObj.NotifyDatasetchanged() not working Due to i have not implemented addAll() method for this class,i cant understand how to write this Method so how can i Write Add All method for this ArrayAdaper class..can Any one help me please
Do you have specific need for subclassing? If you need to have some logic better have one ArrayAdapter as member instance and proxy its methods. Because the original ArrayAdapter already has all these methods readily available

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