Android global variables, getter, setter, error, - java

I try this to add some data to "global variables". Class "Conection" without window in void
for (int in = 7; in < arAll.length; in++) {
if (arAll[in].toString().endsWith("/")) {
((MyApplication) this.getApplication()).setPath(arAll[in]
.toString());
} else {
((MyApplication) this.getApplication()).setFile(arAll[in]
.toString());
}
MyApplication getter's and setter's:
private ArrayList<String> file = new ArrayList<String>();
private ArrayList<String> path = new ArrayList<String>();
private ArrayList<String> all = new ArrayList<String>();
public void removeAll() {
this.file.clear();
this.path.clear();
this.all.clear();
}
public int len() {
return this.all.size();
}
public String getStrbyId (int i) {
return this.all.get(i).toString();
}
public ArrayList<String> getFile() {
return this.file;
}
public void setFile(String file) {
this.file.add(file);
setAll(file);
Log.v("",file);
}
public ArrayList<String> getPath() {
return this.path;
}
public void setPath(String path) {
this.path.add(path);
setAll(path);
Log.v("",path);
}
public ArrayList<String> getAll() {
Log.v("",String.valueOf(len()));
return this.all;
}
private void setAll(String all) {
this.all.add(all);
}
In manifest <application android:name="MyApplication"
When I try to execute first void, I have an error.

The fact that you are using global variables via the Application context very likely that there is something improperly designed in your app. You should not need to use global variables like this at all, and it may be a potential source of your error (passing around the context and getting access to these global variables is sometimes necessary, but perhaps not in this situation). Instead what you should do is pass the necessary variables between components and use them within each component. (Activity, Service, ContentProvider.) So perhaps instead of trying to get this hacky thing working, you could rethink why you need global variables.

Related

Java Array of InnerClass throwing java.lang.NoSuchFieldError

I am trying to brushup java after a long time.
Any help is much appreciated.
For demonstration I have Animal Class that has an array of innerclass of Organs.
public class Animal
{
String nameOfAnimal;
Organs [] vitalOrgans = new Organs[3];
public Animal()
{
}
public String getNameOfAnimal() {
return nameOfAnimal;
}
public void setNameOfAnimal(String nameOfAnimal) {
this.nameOfAnimal = nameOfAnimal;
}
#Override
public String toString() {
return "Animal{" + "nameOfAnimal=" + nameOfAnimal + "}";
}
class Organs{
String nameOfOrgan;
public String getNameOfOrgan() {
return nameOfOrgan;
}
public void setNameOfOrgan(String nameOfOrgan) {
this.nameOfOrgan = nameOfOrgan;
}
#Override
public String toString() {
return "Organs{" + "nameOfOrgan=" + nameOfOrgan + '}';
}
}
}
Now in driver file when I make call there is no syntactical error but I get "Exception in thread "main" java.lang.NoSuchFieldError: vitalOrgans"
Animal mamal = new Animal();
mamal.setNameOfAnimal("Chimp");
mamal.vitalOrgans[0].setNameOfOrgan("Heart");
System.out.println(mamal.vitalOrgans[0].getNameOfOrgan());
What would be the way to make this (or similar idea) to work.
Thanks.
You would need to initialize the vitalOrgrans with new Organs(). Like:
public Animal() {
for (int i = 0; i < vitalOrgans.length; i++) {
vitalOrgans[i] = new Organs();
}
}
Because when you say :
Organs[] vitalOrgans = new Organs[3];
You are creating an array of 3 null Organs. Hence the null pointer exception, when accessing "vitalOrgans[i].".
Taking the relevant bit of code:
public class Animal
{
//...
Organs [] vitalOrgans = new Organs[3];
//...
}
Since your declaration of vitalOrgans was never given an access modifier (i.e. one of private, public, protected) it took on default access, which means only other classes in the same package can see it. Since your other block of code is not in the same package, it cannot see the field.
A minimally viable modification to just make it work would be to set the access to public:
public class Animal
{
//...
public Organs [] vitalOrgans = new Organs[3];
//...
}
While this works, it's not necessarily the best solution, as if you ever change how vitalOrgans is represented, or need to perform any validation, those edits would have to be done throughout the application. Thus, a better solution (and also, a major stylistic convention in Java for those exact reasons) is to make it (and all your fields, in fact) private and access via methods:
public class Animal {
private String nameOfAnimal;
private Organs[] vitalOrgans = new Organs[3];
//...
public Organs[] getVitalOrgans() {
return vitalOrgans;
}
//Alternative accessor that fetches only one organ.
public Organs getVitalOrgan(int index) {
if(index >= 0 && index < vitalOrgans.length)
return vitalOrgans[index];
else
return null;
}
public void setVitalOrgans(Organs[] vitalOrgans) {
this.vitalOrgans = vitalOrgans
}
//...
}
Your caller could then access Organs via either form of the get method (note, you probably want Organs to be public):
Animal.Organs futureMammalHeart = mamal.getVitalOrgan(0); //Animal.Organs due to Organs being an inner class.
if(futureMammalHeart != null) //Demonstration of null check. Safety first!
futureMammalHeart.setNameOfOrgan("Heart");
Animal.Organs[] mammalianVitalOrgans = mamal.getVitalOrgans();
if(mammalianVitalOrgans != null) //Just in case...
System.out.println(mamal.mammalianVitalOrgans[0].getNameOfOrgan());
Also, as Ari mentioned in his answer, don't forget to initialize the organs in your array, otherwise you will get a NullPointerException!

How do I check if an instance of a class has access to a method in another class?

I'm working on a small project where I want to have a list of a class called "DevelopmentEmployee", but only one of them is allowed to manipulate certain methods in another class "Project". The way I have implemented it, the class Project has a field called projectLeader, which is of the type DevelopmentEmployee. When a DevelopmentEmployee attempts to access methods in the class Project, I want to check if the DevelopmentEmployee is equal to the specific instance of Project's projectLeader.
Something like
public class Project {
private DevelopmentEmployee projectLeader;
private List < Activity > activities = new ArrayList < Activity > ();
public Project(DevelopmentEmployee pL) {
this.projectLeader = pL;
}
public void addActivity(String activityName) {
if (projectLeader.equals(DevelopmentEmployee * ) {
activities.add(activity);
}
}
}
But I can't figure out a way to make the access requirement work. How can the instance of the class Project know who is trying to access it?
You should also pass the DevelopementEmployee in addActivity for checking it against the projectLeader.
public void addActivity(String activityName,DevelopmentEmployee employee) {
if (projectLeader.equals(employee) {
activities.add(activity);
}
}
Then you need to override equals method in DevelopmentEmployee class, for proper checking of equality, like the one as shown below :
public boolean equals(DevelopementEmployee e){
if(e!=null && this.employeeId==e.employeeId)
return true;
else
return false;
}
Several possibilities come to mind:
Provide the instance of the one accassing the project method to the method:
public void addActivity(String activityName, DevelpmentEmployee user) {
if (projectLeader.equals(user)) {`
Create some class that holds information about active user and use that inside the methods:
public class Project {
private UserRegistry userRegistry;
private List<Activity> activities = new ArrayList<Activity>();
public Project(UserRegistry userRegistry) {
this.userRegistry = userRegistry;
}
public void addActivity(String activityName) {
if (userRegistry.isActiveUserProjectLeader()) {
activities.add(activity);
}
}
}
public class UserRegistry {
private DevelpmentEmployee projectLeader;
private DevelpmentEmployee activeUser;
private List<DevelpmentEmployee> user;
public void addUser(DevelpmentEmployee user) { ... }
public void makeProjectLeader(DevelpmentEmployee newLeader) { ... }
public void makeActiveUser(DevelpmentEmployee newActiveUser) { ... }
public boolean isActiveUserProjectLeader() { ... }
}`

How can I add a value to an ArrayList from an inner method?

I am currently trying to add a value to an ArrayList object from a method inside of another class.
Here is the class I have created for the ArrayList Object:
public class ArrayClass {
public static ArrayList<String> array = new ArrayList<>();
public static void add_val(String s){
array.add(s);
}
public static int get_size(){
return array.size();
}
public static String get_val(int i){
return array.get(i);
}
}
And the other class where I attempt to edit the ArrayList object:
ArrayClass fill = new ArrayClass();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_explore);
Response.Listener<String> responseListener4 = new Response.Listener<String>(){
#Override
public void onResponse(String response) {
try {
JSONObject jsonResponse4 = new JSONObject(response);
boolean success = jsonResponse4.getBoolean("success");
if (success){
int l;
String filled;
int length4 = jsonResponse4.length();
for (l=0;l<length4;l++){
filled = jsonResponse4.getString(l+"");
fill.add_val(filled);
}
}else{
AlertDialog.Builder builder = new AlertDialog.Builder(ExploreActivity.this);
builder.setMessage("Could not retrieve restaurant tables filled")
.setNegativeButton("Retry", null)
.create()
.show();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
};
FilledRequest filledRequest = new FilledRequest(responseListener4);
RequestQueue queue4 = Volley.newRequestQueue(ExploreActivity.this);
queue4.add(filledRequest);
If you look in the onResponse method, you can see the attempt to add a value from the jsonResponse into the ArrayClass object. However, when I launch my app, it does not add the value into the object. I'm used to python global variables and not having to deal with the semantics of java, so if you could shed some light on what changes need to be made, I would greatly appreciate it.
Apart from other given answers/solutions to the issue you are facing, let me share a best and optimized way to implement JSON parsing in Android.
I would suggest you to check GSON or Jackson libraries which provides Java serialization/deserialization that can convert Java Objects into JSON and back.
There are some benefits it does provide, one of the main benefits is you do not need to implement parsing manually and less chances of mistakes in implementing parsing, like you may make a mistake in mentioning key "Success" or "success" or any such silly mistakes!
Firstly, since your variable is static, and the methods are static too, you don't have to instantiate the object. You could do something like this:
ArrayClass.add_val("Hello");
But if you want to instantiate then you can do this:
public class ArrayClass {
private ArrayList<String> array;
public ArrayClass() {
array = new ArrayList<>();
}
public void add_val(String s){
array.add(s);
}
public int get_size(){
return array.size();
}
public String get_val(int i){
return array.get(i);
}
}
To make sure the values are filled in, you can check the array size like this:
for (l=0;l<length4;l++){
filled = jsonResponse4.getString(l+"");
fill.add_val(filled);
}
Log.d("TEST", String.valueOf(fill.get_size());
Remove all cases of the static keyword in ArrayClass. Static methods are class level methods, ie. are called on the class itself, rather than an instance of the class.
You can also try this, for ArrayList:
First do some changes in your ArrayClass. Use get And Set method to access your array.
public class ArrayClass {
private ArrayList<String> array = new ArrayList<>();
public ArrayList<String> getArray() {
return array;
}
public void setArray(ArrayList<String> array) {
this.array = array;
}
}
And your other class where you attempt to edit the ArrayList use getArray And SetArray method and some predefined method of ArrayList like this:
Store the data in ArrayList:
for (l=0;l<length4;l++){
filled = jsonResponse4.getString(l+"");
fill.getArray().add(filled);
}
Get Size of ArrayList:
fill.getArray().size();
And also you can store an another ArrayList like
ArrayList<String> tempArrayList = new ArrayList<String>();
tempArrayList.add("string 1");
tempArrayList.add("string 2");
tempArrayList.add("string 3");
tempArrayList.add("string 4");
fill.setArray(tempArrayList)

Java: message system needs to be able to pass various objects

I'm writing a messaging system to queue actions for my program to execute. I need to be able to pass various objects by the messages. I currently have a Msg object that accepts (Action enum, Data<?>...object). The Data object is intended to be a wrapper for any object I might pass.
Currently the Data object uses this code, with generics:
public class Data<T> {
private T data;
public Data(T data){
this.data = data;
}
public T getData(){
return data;
}
}
The Msg object takes Data<?>... type, so Msg has a Data<?>[] field.
If getData() is called on a Data<?> object, it returns the Object type. Obviously not ideal.
I need to be able to pass, say, Image objects as well as String objects. I'm certain there's a better way of passing arbitrary data.
The reason you're having trouble is that you're trying to get the static typing system of Java to do something that it can't. Once you convert from a Data<T> to a Data<?>, whatever T was is effectively lost. There's no clean way to get it back.
The quickest way to get it to work (from what you have right now) is to start throwing casts everywhere, like this:
Data<?> d = new Data("Hello");
String contents = (String)d.getData();
This is kind of a terrible idea, so let's go back to the drawing board.
If (ideally), you have all of the types you could ever need ahead of time (i.e. every Data is either a String or an Image or an Integer), then you can pretty easily (though it's a bit tedious) define a Sum type (aka a union if you're coming from C) of the different types of data you'll have to handle. As a class invariant, we assume that exactly one of the fields is non-null, and the rest are null. For this example I'll assume it can be either a String, an Image, or an Integer, but it's fairly simple to add or remove types from Data as necessary.
public class Data {
private Image imgData;
private String stringData;
private Integer intData;
public Data(Image img) {
this.imgData = img;
}
public Data(String stringData) {
this.stringData = stringData;
}
public Data(Integer intData) {
this.intData = intData;
}
public boolean isImage() {
return imageData != null;
}
public boolean isInteger() {
return intData != null;
}
public boolean isString() {
return stringData != null;
}
public Image asImage() {
if(! isImage()) throw new RuntimeException();
return imgData;
}
public Image asString() {
if(! isString()) throw new RuntimeException();
return stringData;
}
public Image asInt() {
if(! isInt()) throw new RuntimeException();
return intData;
}
}
One necessary side effect is that we cannot wrap null without causing exceptional behavior. Is this is desired, it isn't too difficult to modify the class to allow for it.
With this Data class, it's pretty easy to do if-else logic to parse it.
Data d = ....... //Get a data from somewhere
if(d.isImage()) {
Image img = d.asImage();
//...
} else if (d.isString()) {
String string = d.asString();
//...
} else if (d.isInteger()) {
Integer i = d.asInt();
//...
} else {
throw new RuntimeException("Illegal data " + d + " received");
}
If you call getData().getClass() you will get the class or type that was passed, which doesn't seem to me to be the same as an Object. You might not know what you are getting, but you can either find out or define a common interface for everything you might pass. You could for example, call toString() or getClass() on anything passed. Your question is that you are passing any conceivable object, so my question is what are you going to do with it? If you are going to serialize it into a database you don't need know anything about what type it is, otherwise you can test it or call a common interface.
public class PlayData {
class Msg {
private List<Data<?>> message = new ArrayList<Data<?>>();
public void addData(Data<?> datum) { message.add(datum); }
public void printTypes() { for ( Data<?> datum: message ) { System.out.println(datum.getData().getClass()); } }
}
class Data<T> {
private T value;
public Data(T value) { this.value = value; }
public T getData() { return value; }
}
class Listener {
public void receive(Msg msg) { msg.printTypes(); }
}
class Sender {
private Listener listener;
public Sender(Listener listener) { this.listener = listener; }
public void send(Msg msg) { listener.receive(msg); }
}
class MyPacket {
int i;
public MyPacket(int i) { this.i = i; }
}
public static void main(String[] args) throws Exception { new PlayData().run(); }
public void run() throws Exception {
Sender sender = new Sender(new Listener());
Msg msg = new Msg();
msg.addData(new Data<String>("testing") );
msg.addData(new Data<MyPacket>(new MyPacket(42)) );
sender.send(msg);
}
}

Why am I getting this ClassCastException? Working on eclipse, but not in intelliJ

I have this class named RiddlesHolder:
public class RiddlesHolder extends Application {
ArrayList<String> funnyRiddles = new ArrayList<String>();
ArrayList<String> funnyRiddlesAnswers = new ArrayList<String>();
ArrayList<String> KidsRiddles = new ArrayList<String>();
ArrayList<String> KidsRiddlesAnswers = new ArrayList<String>();
ArrayList<String> AnimalRiddles = new ArrayList<String>();
ArrayList<String> AnimalRiddlesAnswers = new ArrayList<String>();
public void addAnimalRiddles(){
AnimalRiddles.add("1");
AnimalRiddles.add("2");
}
public void addAnimalRiddlesAnswers(){
AnimalRiddlesAnswers.add("1");
AnimalRiddlesAnswers.add("2");
}
public void addFunnyRiddles(){
funnyRiddles.add("1");
funnyRiddles.add("2");
}
public void addFunnyRiddleAnswers(){
funnyRiddlesAnswers.add("1");
funnyRiddlesAnswers.add("2");
}
public void adKidsRiddles(){
KidsRiddles.add("1");
KidsRiddles.add("2");
}
public void addKidsRiddlesASnswers(){
KidsRiddlesAnswers.add("1");
KidsRiddlesAnswers.add("2");
}
public ArrayList<String> getAnimalRiddles() {
return AnimalRiddles;
}
public ArrayList<String> getAnimalRiddlesAnswers() {
return AnimalRiddlesAnswers;
}
public ArrayList<String> getFunnyRiddles() {
return funnyRiddles;
}
public ArrayList<String> getFunnyRiddlesAnswers() {
return funnyRiddlesAnswers;
}
public int getFRiddleByContent(String content) {
return funnyRiddles.indexOf(content);
}
public ArrayList<String> getKidsRiddles() {
return KidsRiddles;
}
public ArrayList<String> getKidsRiddlesAnswers() {
return KidsRiddlesAnswers;
}
public int getKidsRiddleByContent(String content) {
return KidsRiddles.indexOf(content);
}
}
and this line inside of the activity's onCreateView:
final RiddlesHolder riddles = (RiddlesHolder) getActivity().getApplication();
and it throws the following error:
java.lang.ClassCastException: android.app.Application cannot be cast to com.tc.tools.RiddlesHolder
at com.tc.gatanki.FunnyRiddles$PlaceholderFragment.onCreateView(FunnyRiddles.java:104)
What am I missing here? I'm a bit confused, because this is working code. I'm just moving from eclipse to the new android studio powered by intelliJ(suggested by google even if it is still in a BETA stage). Why am I getting this error in my code? I know that I'm missing an extremely small part here, but I'm not able to spot it at the momment.
The custom Application injection is driven by the AndroidManifest.xml, so if it's not your application class being instantiated, that could be due to the AndroidManifest.xml being incorrect. Can you check how it looks like in Android Studio, or even in the APKs that the two IDEs generated? There should be an attribute on the <application> tag something like android:name="om.tc.tools.RiddlesHolder".

Categories

Resources