I have created a singleton ArrayList class in android which is following.
public class SingletonArrayList {
private static SingletonArrayList mInstance;
private ArrayList<String> userNameList = null;
public static SingletonArrayList getInstance() {
if(mInstance == null)
mInstance = new SingletonArrayList();
return mInstance;
}
private SingletonArrayList() {
userNameList = new ArrayList<String>();
}
// retrieve array from anywhere
public ArrayList<String> getArray() {
return this.userNameList;
}
//Add element to array
public void addToArray(String value) {
userNameList.add(value);
}
}
I'm calling this singleton ArrayList in my activity2. It's working fine there(it contains data!).
activty2:
ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, SingletonArrayList.getInstance().getArray());
But in activtiy1 it's returing an empty list.
activity1:
Log.i("single",SingletonArrayList.getInstance().getArray().toString());
if(SingletonArrayList.getInstance().getArray().contains(username1)) {
Toast.makeText(getApplicationContext(), "Username already Exists. Please select a different username", Toast.LENGTH_LONG).show();
return;
}
Basically, the problem is that ArrayList is coming empty in one activity and contains data in another activity. Any solutions?
Related
ArrayList<String> stepsList = new ArrayList<>();
ArrayList<Integer> stepsPosList = new ArrayList<>();
stepsAdapter = new ArrayAdapter<String>(this,R.layout.steps_item,R.id.etStepsDetails,stepsList);
stepsAdapter2 = new ArrayAdapter<Integer>(this,R.layout.steps_item,R.id.tvStepsPosition,stepsPosList);
stepsView.setAdapter(stepsAdapter);
stepsView2.setAdapter(stepsAdapter2);
Is it possible to combine the 2 array adapter into 1? The layout is on the same page but I need 2 id and 2 array list into each. and then call the list view.
POJO CLASS
public class CombineData {
ArrayList<String> stepsList;
ArrayList<Integer> stepsPosList;
public CombineData(ArrayList<String> stepsList,ArrayList<Integer> stepsPosList){
this.stepsList = stepsList;
this.stepsPosList = stepsPosList;
}
public CombineData(){
}
public ArrayList<String> getStepsList() {
return stepsList;
}
public void setStepsList(ArrayList<String> stepsList) {
this.stepsList = stepsList;
}
public ArrayList<Integer> getStepsPosList() {
return stepsPosList;
}
public void setStepsPosList(ArrayList<Integer> stepsPosList) {
this.stepsPosList = stepsPosList;
}
}
THIS LINE SHOWS AN ERROR : CANNOT RESOLVE CONSTRUCTOR ARRAYADAPTER... int,int,ArrayList
stepsAdapter = new ArrayAdapter<CombineData>(this,R.layout.steps_item,R.id.etStepsDetails,stepsList);
you should make POJO class
class CombineData(
ArrayList<String> stepsList,
ArrayList<Integer> stepsPosList
)
{
getter()/setter()
}
then change adapter
stepsAdapter = new ArrayAdapter<CombineData>(this,R.layout.steps_item,R.id.etStepsDetails,stepsList);
Now, you can access in the listview like this
item.stepsList
item.stepsPosList
I am using an ArrayList in my application.
I would like to know the exact procedure to initialize my ArrayList from a Singleton class.
The data will be used in some other Activities.
Can anybody help to know about Singleton class?
Here is how to create your singleton class :
public class YourSingleton {
private static YourSingleton mInstance;
private ArrayList<String> list = null;
public static YourSingleton getInstance() {
if(mInstance == null)
mInstance = new YourSingleton();
return mInstance;
}
private YourSingleton() {
list = new ArrayList<String>();
}
// retrieve array from anywhere
public ArrayList<String> getArray() {
return this.list;
}
//Add element to array
public void addToArray(String value) {
list.add(value);
}
}
Anywhere you need to call your arrayList just do :
YourSingleton.getInstance().getArray();
To add elements to array use :
YourSingleton.getInstance().addToArray("first value");
or
YourSingleton.getInstance().getArray().add("any value");
Please look at the following wikipedia-artikle:
https://en.wikipedia.org/wiki/Singleton_pattern
But keep in mind that singletons are 'global state' and make your sourcecode harder to test. There are lot of people saying: "singletons are evil'
I think you need something like this.
public class SingletonClass {
private static ArrayList<String> strArray;
private static SingletonClass singleton;
private SingletonClass(){}
public static synchronized SingletonClass getConnectionInstance(ArrayList<String> strArray){
if (singleton == null) {
singleton = new SingletonClass();
}
this.strArray = strArray;
return singleton;
}
}
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)
My Arraylist Only stores one object in it. Every time a new object is entered, it overwrites the current one.
Calling method:
public void saveBookingInfo(View view) {
EditText applicantNameText = (EditText) findViewById(R.id.applicantNameTextField);
EditText itemToBurnText = (EditText) findViewById(R.id.itemToBurnTextField);
String appName = applicantNameText.getText().toString();
String appItemToBurn = itemToBurnText.getText().toString();
if (appItemToBurn.isEmpty() || appName.isEmpty()) {
Toast.makeText(BookingScreen.this, "Please fill in all fields.", Toast.LENGTH_SHORT).show();
}
else {
sendApplication.storeApplication(appName, appItemToBurn);
this.finish();
}
}
ArrayList method:
public void storeApplication(String name, String item){
ArrayList<Application> peopleAttending = new ArrayList<>(10);
peopleAttending.add(new Application(name, item));
}
You're declaring the List<Application> as local parameter to the method. Move it as a field in the class instead.
private List<Application> peopleAttending = new ArrayList<>();
public void storeApplication(String name, String item) {
peopleAttending.add(new Application(name, item));
}
You are creating a new ArrayList every time you call the method. You should create the ArrayList exactly once and pass a reference to the method, or make the reference an instance variable.
you can try changing the constructor of the class for object sendApplication
class SendApplication{
List<Application> peopleAttending = null;
public SendApplication(){
List<Application> peopleAttending = new ArrayList<Application>();
}
public void storeApplication(String name, String item) {
peopleAttending.add(new Application(name, item));
} //...... other methods follow
}
I have an Android app which keeps a persistent log of events in a custom object that extends ArrayList. It is kept in a singleton so that various activities all point to the same one log. The main activity reloads the list in the onResume.
Problem is, when I reload the log, all the UI elements (like the ArrayAdapter) lose the reference and I need to set them up again. It works. But, it seems like a lot of work.
How can I reload the object into the original object's instance so that I don't have to do all that setup again? Using a singleton should make it easier not harder.
I know it's all a problem with pass-by-reference. But I just can't get my head around it.
Java is not my first language... Thanks.
Activity onCreate:
dataLog = DataLog.getInstance();
logView = (ListView) findViewById(R.id.logView);
dataLogAdapter = new ArrayAdapter<String>(this,R.layout.log_row, dataLog);
logView.setAdapter(dataLogAdapter);
Activity onResume:
dataLog = Persister.recoverLog(this, "datalog.dat");
dataLogAdapter = new ArrayAdapter<String>(this,R.layout.log_row, dataLog);
logView.setAdapter(dataLogAdapter);
Persister:
public static DataLog recoverLog(Context context, String fileName){
File file = context.getFileStreamPath(fileName);
DataLog obj = new DataLog ();
if(file.exists() && file.length()>0){
FileInputStream fis = null;
ObjectInputStream ois = null;
try {
fis = new FileInputStream(file);
ois = new ObjectInputStream(fis);
obj = (DataLog) ois.readObject();
ois.close();
fis.close();
} catch (IOException ex) {
ex.printStackTrace();
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
}
}
return obj;
}
DataLog:
public class DataLog extends ArrayList<String> implements Serializable {
private static final long serialVersionUID = 0L;
public DataLog() {}
private static DataLog _instance;
public static DataLog getInstance() {
if(_instance==null){
_instance = new DataLog();
}
return _instance;
}
public boolean add(String entry) {
super.add(entry);
return true;
}
public void add(int index, String entry) {
if (index > 0)
super.add(index, entry);
else
super.add(entry);
}
public void clear() {
super.clear();
}
}
Your datalog isn't a true singleton. If it were, no new reference would be created after it was created the very first time.
This:
dataLog = Persister.recoverLog(this, "datalog.dat");
should not return a Datalog but some internal data DataLog uses (an ArrayList of Strings) and should be called within DataLog
Then only pass the dataLog instance around. If you ever reassign it you'll have problems. When you reload data log you'll need to reload the structures relying on DataLog's array instance.
Handle reloading your DataLog data in onResume if necessary, but do it like so:
DataLog.getInstance().load();
So that your data log is never reassigned. That's the key. DataLog is a wrapper around your data. If DataLog's internal state is changed, no references to DataLog are lost.
Here's an example:
public class DataLog implements Serializable {
//internalize this data.
private ArrayList<String> data;
private static final long serialVersionUID = 0L;
//singleton's constructor should be private.
private DataLog() {}
private static DataLog _instance;
public static DataLog getInstance() {
if(_instance==null){
_instance = new DataLog();
}
return _instance;
}
public ArrayList<String> getData(){
//copy this if you're worried about it being modified.
//DO NOT pass this reference around. Pass a reference to data log,
//reload GUI relying on this reference as needed.
return data;
}
public void load(){
data = //reload string array from disk.
}
public boolean add(String entry) {
super.add(entry);
return true;
}
public void add(int index, String entry) {
if (index > 0)
data.add(index,entry);
else
data.add(entry);
}
public void clear() {
data.clear();
}
}