Problem accessing variable[] from another class - java

I know this a pretty basic question, and already found another ones like mine, but I honestly don't know what I'm doing wrong.
public class InteractiveArrayAdapter extends ArrayAdapter<Model> {
private final List<Model> list;
private final Activity context;
public int teste;
public InteractiveArrayAdapter(Activity context, List<Model> list) {
super(context, R.layout.rowbuttonlayout, list);
this.context = context;
this.list = list;
}
public int getTest()
{
return teste;
}
static class ViewHolder {
protected TextView text;
protected CheckBox checkbox;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
teste = 2;
....
}
}
and other class:
try{
InteractiveArrayAdapter adapt = new InteractiveArrayAdapter(this,
getAPPS(0));
int test = adapt.getTest();
Toast.makeText(this, Integer.toString(test), Toast.LENGTH_LONG).show();
Log.v("TAG",Integer.toString(test));
}catch(Exception e)
{
Log.v("EXCEPTION",e.toString());
}
EDIT: I was getting null for a stupid mistake, and now I'm getting the primitive and expected 0 as most of you say.
At some point of my app, everytime a checkboxes is clicked that method getView is executed. I want to store that to an array[] of strings progressively (i+1) (i just put int to be easier to understand - realize now it was a mistake), and then when users inputs ok I want to access the whole array. Wondering if it's possible the way I want.
So when I do this
InteractiveArrayAdapter adapt = new InteractiveArrayAdapter(this,
getAPPS(0));
This is meaningless, because I don't need to execute anything again, I just want to retrieve the created array - if possible!

Your code won't even compile. return this.teste; should be return this.test;.

Well, this isn't a direct copy/paste, since this obviously wouldn't compile. Whenever you're dealing with an actual error or issue, it's really best to paste the actual code. We're all programmers, so we can read it.
But based on the structure you've shown above, either the typo you've put in the line return this.teste (should be return this.test) is in your code, or you didn't initialize the instance variable test in your constructor.
Without showing us the actual code you're writing, it's impossible to say (especially the section that initializes the test variable, and the part that returns its value are missing - we're not mind readers, I'm afraid).
So, those are two potential candidates. On another note, however, if you mark the test variable as public, then you don't need to have getter/setter methods for them, since any class can access them without going through a method call. That's what public does.

But that is what should happen according to your code. You don't call B method to update teste variable.

Related

Android - This Class Should Provide a Default Constructor

When i want to Generate Signed app it tells me :
Error:Error: This class should provide a default constructor (a public constructor with no arguments) (com.example.discopc.beautiyuser.Customy) [Instantiatable]
My Project :
public class Customy extends ArrayAdapter<String> {
private final Activity context;
View v;
private final String[]name;
public Customy(Activity context, String[] name){
//super(null,0);
super(context,R.layout.activity_customy,name);
this.context=context;
this.name=name;
}
public View getView(final int position,View convertView,ViewGroup parent){
try{
LayoutInflater infalter=context.getLayoutInflater();
v=infalter.inflate(R.layout.activity_customy,null,true);
TextView txtName=(TextView)v.findViewById(R.id.name);
txtName.setText(""+name[position]+"");
}catch(Exception e){
}
return v;
}
}
Note: It works fine when debugging on my android device but i cant
Build > Generate Signed app
I Really don't know what to do.
Thanks ,
Check by mistake you have added that adapter name in Android Manifest. If yes, remove that and try.
A default constructor is a constructor for a class which has no arguments and can be used implicitly.
public Customy( /* notice - no arguments */) {
// your code here
}
But in your case - this must not be the issue. The issue is that you have this class somewhere in your XML configuration where some framework is trying to instantiate it using a default constructor, while we obviously see that you need to pass 2 parameters to your constructor for the class instance to function.

Accessing and using custom Objects and ArrayList<Object> in different methods

I am currently working on an app that will use many objects as information holders (music things - artist, song, id of album cover img, and another id of 2nd img).
I decided that it would be the best to create "Track" class and use it to make objects and store them in ArrayList.
I created the class, I created the list, but I'm having trouble with accessing it (I want to change the ImageViews and TextViews basing on current Track object).
Here's the Track Class: (Track.java separate)
public class Track {
private String mNameArtist;
private String mNameTrack;
private int mTabResource;
private int mCoverResource;
public Track(String nameArtist, String nameTrack, int tabResourceId, int coverResourceId){
mNameArtist = nameArtist;
mNameTrack = nameTrack;
mTabResource = tabResourceId;
mCoverResource = coverResourceId;
}
public String getArtistName() {
return mNameArtist;
}
public String getTrackName() {
return mNameTrack;
}
public int getTabResourceId() {
return mTabResource;
}
public int getCoverResourceID() {
return mCoverResource;
}}
And here's ArrayList declaration: (PlayActivity.java, inside onCreate method)
ArrayList<Track> Tracks = new ArrayList<Track>();
Tracks.add(new Track("Artist Name", "Track Name", R.drawable.tabtemplate, R.drawable.testcover));
Tracks.add(new Track("Pink Floyd", "Comfortably Numb Solo 1", R.drawable.CNS1Tab, R.drawable.pink_floyd_the_wall));
There are more positions, but you get the idea.
Everything seems to work fine up to this point.
When I want to access it inside another method (even in the same PlayActivity.java) nothing happens or I see errors. I tried many different approaches but every single one fails. For example:
Track.getTabResource(); // can't even use the method.
Tracks.get(3); // does not work as well.
I just can not use objects or that arraylist inside my methods. The "Tracks array" won't even show up in Android Studio when typing. Track does, but I can't access positions from Array.
So to sum up, is there any other way I can use my Objects (ArrayList) items inside other classes and methods?
Thank you for your help in advance.
Create List as instance variable and access through Object of that class.
public class PlayActivity {
List<Track> tracks = new ArrayList<Track>();
public void onCreate() {
tracks.add(new Track("Artist Name", "Track Name", R.drawable.tabtemplate, R.drawable.testcover));
tracks.add(
new Track("Pink Floyd", "Comfortably Numb Solo 1", R.drawable.CNS1Tab, R.drawable.pink_floyd_the_wall));
}
public List<Track> getAllTracks() {
return Collections.unmodifiableList(tracks);
}
public Track getTrack(int index) {
return tracks.get(index);
}
}

Force a user of my library to implement an interface or extend an abstract class

I'm developing an android library (.aar) and I was wondering if it was possible to, as the title suggest, force a user to implement an interface or extend an abstract class of my library.
I already know that I could just go with a class like this in my library :
public class MyLibrary
{
public interface VariablesInterface
{
void createVariables();
}
private static VariablesInterface vi = null;
public void setVariablesInterface(VariablesInterface v)
{
vi = v;
}
private static void SomeWork()
{
if (vi == null)
{
throw new RuntimeException("You noob.");
}
else
{
// do work
}
}
}
The library will work "alone" at some point, and when it will come to SomeWork(), if the interface isn't implemented it will crash, but this could only be seen at runtime.
Is there a way to have this behaviour when compiling the user's application ?
The goal is to avoid the user forgetting that he have to implement this without having to write it in the documentation and hope the user will probably read it.
Thanks for reading !
EDIT
I think that this question need some enhancement and background.
The purpose of the library is to provide classes that create variables which manages preferences, e.g. :
public class VarPreferenceBoolean extends VarPreference
{
private boolean defaultValue;
public VarPreferenceBoolean(String key, boolean defaultValue)
{
super(key, true);
this.defaultValue = defaultValue;
}
public void setValue(Context context, boolean value)
{
SharedPreferences.Editor e = context.getSharedPreferences(PropertiesManager.preferenceFileName, Context.MODE_PRIVATE).edit();
e.putBoolean(key, value);
e.commit();
}
public boolean getValue(Context context)
{
readPropFile(context);
SharedPreferences sp = context.getSharedPreferences(PropertiesManager.preferenceFileName, Context.MODE_PRIVATE);
return sp.getBoolean(key, defaultValue);
}
}
The same goes for int, string and so on.
In the super class, I add each VarPreference to a List to keep the library acknowledged of all the variables availables.
Note the readPropFile inside the getter.
Then, the user use the library in his project like this :
public class Constants
{
public static final VarPreferenceInt FILETYPE;
public static final VarPreferenceInt DATAMODE;
public static final VarPreferenceString URL_ONLINE;
public static final VarPreferenceBoolean UPDATING;
public static final VarPreferenceLong LAST_UPDATE;
static
{
FILETYPE = new VarPreferenceInt("FileType", MyFile.FileType.LOCAL.getValue());
DATAMODE = new VarPreferenceInt("DataMode", DataProvider.DataMode.OFFLINE.getValue());
URL_ONLINE = new VarPreferenceString("UrlOnline", "http://pouetpouet.fr");
UPDATING = new VarPreferenceBoolean("Updating", false);
LAST_UPDATE = new VarPreferenceLong("LastUpdate", 0L);
}
}
Now, when the user call an accessor, readPropFile will first search if a .properties file exist and modify accordingly the preferences if it found matches between the list of VarPreference and the properties of the file. Then it will delete the file and the accessor will return the value.
This is what exists today.
Now we want another application (let's say Pilot) to be able to get the VarPreferences of the user's application (let's say Client). Both implements the library.
Pilot send an Intent asking for the VarPreference list of Client, putting in extra the package name of Client.
The library receive the intent, verify the packagename, if it's Client it send back the list.
Problem is, if Client hasn't started, no VarPreference exists, and the list is empty.
I need to force the user to create his VarPreference in an method that my library know, to be able to call it whenever I want, and create the VarPreferences of the user when it's necessary.
Hope this is clearer !
EDIT
I rethought about all of this with a colleague and it just hit us that all this stack is biaised.
I didn't explain well and even if I said it, I didn't take account enough of this : everything needs to be done from the library.
So, even if I give an interface to the library, the application will have to run and call this affectation first in order to let the library work alone.
We are heading towards introspection now.
(This is the goal, it may not be possible...)
There will be an abstract class inside the library, with an abstract method where the user will place all of the VarPreferences creations. The user will have to extends this class and call the method in order to create his VarPreferences.
In the library, a method will search by introspection a child of the abstract class, create an instance of this child and call the method that will create the VarPreferences.
I would leave the abstract classes and interfaces in the main library and load the rest of your code via classloader from another. JDBC works like this.
Is there a way to have this behaviour when compiling the user's application ?
I see no way to force a compilation failure. However, if you force them to supply a VariablesInterface in the constructor then it will fail immediately. Make the VariablesInterface be final and only initialize it in the constructor:
public class MyLibrary {
private final VariablesInterface vi;
public MyLibrary(VariablesInterface vi) {
if (vi == null) {
throw new IllegalArgumentException("vi can't be null");
}
this.vi = vi;
}
...
If you can't change the constructor then you can also add to any SomeWork public methods some sort of configuration check method to make sure the the vi wiring has properly been done but this requires careful programming to make sure all public methods are covered.
public void somePublicMethod() {
checkWiring();
...
}
private void checkWiring() {
if (vi == null) {
throw new IllegalStateException("vi needs to be specified");
}
}

Avoiding != null using a method in java

In my example below I want to avoid writing getView != null every time I want to use getView. To keep it cleaner I create a method hasView() which does the check for me. However I still get a warning. Is there any way around this?
import android.support.annotation.Nullable;
public void showView(){
if(hasView()){
getView().show(); // Shows warning Method invocation 'showLoading' may produce 'java.lang.NullPointerException'
}
}
boolean hasView(){
return getView() != null;
}
#Nullable
private View getView(){
return view;
}
I am using Android Studio/IntelliJ. I know that I can use #SuppressWarnings I have seen this question but this makes the code uglier.
I want to avoid writing getView != null every time I want to use
getView ?
You can use Null Object pattern to avoid checking for != null everywhere in the program, the code is shown below:
(1) Define an EmptyView Class
public EmptyView {
//Define a static emptyView, so that we can reuse the same object
public static final EmptyView emptyView = new EmptyView();
public show() {
//does nothing
}
}
(2) Use the EmptyView in case of no view available:
//other classes:
private View getView(){
if(viewAvailable) {
return view;
} else {
return EmptyView.emptyView;
}
}
public void showView(){
getView().show();
}
You can look at Wiki here more info & Java example.
When you return null from various methods, they will potentially cause the NullPointerException in the programs and will become very hard to debug in larger projects.
So, it is a bad practice to return null from methods (& they should be avoided) and that is the reason Spring API generally return empty list/set objects (instead of null) while trying to retrieve data from DAO/Repository classes (like EmptyView object as explained above).
P.S.: This option works with and without Java8.
If you are using Java8, then prefer to do with Optional as given in the answer from #janos
You might be interested in using an Optional, added in API level 24 of Android, for example:
private Optional<View> getView() {
return Optional.ofNullable(view);
}
public void showView() {
getView().ifPresent(View::show);
}

Android Context not serializable dilemma for class that implements Iteratable

Here is my situation. I have written a Playlist class that stores a context. Playlist has 9 child classes. Unfortunately, to pass Playlist between intents, it must implement Serializable. This is a problem because Playlist stores a context, so that the Iterator can work, as the Iterator method that must be Overridden from Iterator can not accept any parameters. Therefore, I must store Context somewhere as it is needed to determine the size of the Playlist. Here is the (simplified) code.
public abstract class Playlist implements Serializable, Iterable<Song>
{
private static final long serialVersionUID = 0L;
private Context context;
public Context getContext() { return context; }
public Playlist(Context context)
{
this.context = context;
}
public abstract int size(); //getContext() referenced in all currently written children
public abstract Song getSong(int index); //getContext() referenced in all currently written children
#Override
public PlaylistIterator iterator()
{
return new PlaylistIterator();
}
public class PlaylistIterator implements Iterator<Song>
{
private int current;
PlaylistIterator()
{
current = 0;
}
#Override
public boolean hasNext()
{
return current < size(); //SIZE HERE needs access to a context, but this method certainly can not take one, and neither can the constructor above.**
}
#Override
public Song next()
{
if (!hasNext())
throw new NoSuchElementException();
return getSong(current++);
}
#Override
public void remove()
{
throw new UnsupportedOperationException();
}
}
}
I have read that you can store a static context, but that this is poor design. I can not seem to find a way around this.
I have considered adding a static context reference that is assigned in writeObject, and then accessed in readObject, as the transition should be nearly instant because the Serialization implementation is only so that Playlist can be passed in an intent. But even this feels hacky.
Is there a common work around to dealing with the fact that we cannot serialize context? Is my solution acceptable in terms of stability? It might be against the rules, but what is your recommendation in this situation?
I have written a Playlist class that stores a context
That's probably not a good idea.
Unfortunately, to pass Playlist between intents, it must implement Serializable
It could be Parcelable, but that does not solve your problem. A Context cannot go into either a Serializable or a Parcelable.
because Playlist stores a context, so that the Iterator can work,
That's probably not a good idea.
Therefore, I must store Context somewhere as it is needed to determine the size of the Playlist.
Or, the Playlist could hold the size of the playlist. An int is readily able to be used with Serializable or Parcelable.
Or, get rid of the Iterator, as that is not going to work well with Serializable or Parcelable either.
I can not seem to find a way around this.
Have Playlist be a pure model object, with no Context.
Or, depending on the use case, have Playlist be a singleton, using the Application as the Context. It is unclear whether there is only one Playlist or several.
but what is your recommendation in this situation?
Playlist should not hold a Context and should not have an Iterator.

Categories

Resources