I want to populate listview with catalog names which are inside other specific catalog that my application is creating in other activities.
Here's the doInBackground method:
#Override
protected ArrayList<String> doInBackground(Void... arg0) {
ArrayList<String> wynik = new ArrayList<String>();
File katalog = new File(Environment.getExternalStorageDirectory().getPath()+"/DBConnector/Projekty/");
File[] projekty = katalog.listFiles();
for (File projekt : projekty) {
if (projekt.isDirectory()) {
wynik.add(projekt.getName());
}
}
return wynik;
}
It's throwing NullPointerException. As far as I know, even if there were no folders there it just should leave the ArrayList empty and pass it on (I'm using if(result.isEmpty()) later in onPostExecute to give info to user about that or actually populate listview if it's not empty - very similar code worked in other place, where I populated listview with data from resultset). Still, there are multiple folders there. I'm afraid I made some stupid mistake, but I just can't see it. I would appreciate some help.
EDIT: The thing that helped was restarting eclipse. Should have thought about it first though I still have no idea how it could have happened.
Without the logcat it's quite difficult to say for sure.
Are you sure you can access external storage? (Manifest Permission)
Is File Katalog a valid? or just null?
Is File[] projekty returning an empty array?
Use breakpoints and check those points above.
Related
I'm trying to fill a list view with data i'm receiving from and odata service in json format. The data is already fetched and can be accessed with getIODataEntry().
I'm appending the respective values to a string to see an output in LogCat and split the string afterwards to fill my listView with the single values.
ListView listView_CarrierCollection = null;
...
private void showData() {
Log.d("debug", "log 1");
String carrierCollection = "";
for(int i=0; i<getIODataEntry().size(); i++) {
carrierCollection += getIODataEntry().get(i).getPropertyValue("Carrname");
carrierCollection += ";";
}
Log.d("debug", carrierCollection);
ArrayList<String> list = new ArrayList<String>(Arrays.asList(carrierCollection.split(";")));
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(getActivity().getApplicationContext(), R.layout.custom_textview, list);
listView_CarrierCollection.setAdapter(arrayAdapter);
Log.d("debug", "log 2");
}
everything works, but only after my devices' screen has turned off and has being turned on again or after i close and reopen the app. The logs instead are prompted instantly to logcat, but the listView only contains the data after reopening the app.
Am i missing something out? Every hint would be appreciated!
EDIT:
Finally got it to work - turned out it had nothing to do with the posted code above. I had some listeners, that were trying to update a TextField in a Fragment. It seems as if MyFragment.textfield.setText("test"); blocked any further operations in some way. Surrounding it with runOnUiThread(new Runnable(){ ... }) solved it for me and got the whole thing to work.
Nevertheless thank you for your ideas and help!
Late to the party but may help someone else in the future
In my case, I wasn't calling notifyDataSetChanged() when i was updating my mutable array list. Therefore it was only working when i was tuning sceen off and on again. But after calling notifyDataSetChanged() it worked as usual.
Hope it helps ;)
I am creating an app that involves reading in data from a file. The file is relatively large (1.8 MB) and is being read from an async thread in onCreate. The very first time the app is started up, it loads just fine. However, if you click the back button and then load it again, it runs out of memory and crashes (throwing the OutOfMemory error).
How do I get it to use the lowest amount of memory possible and/or free that memory when it is done?
File Reading Code (executed in the doInBackground() method of the async class):
public ArrayList<String> createDataList() {
dataList = new ArrayList<String>();
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(getAssets().open(
"text.txt")));
String data;
while ((data = br.readLine()) != null) {
dataList.add(data);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
br.close(); // stop reading
} catch (IOException ex) {
ex.printStackTrace();
}
}
return dataList;
}
EDIT*
Async Class:
private class loadData extends AsyncTask<Void, Void, ArrayList<String>> {
#Override
protected ArrayList<String> doInBackground(Void... arg0) {
dataList = createDataList();
return dataList;
}
protected void onPostExecute(ArrayList<String> result) {
super.onPostExecute(result);
// display first element in ArrayList in TextView as a test
}
}
I have tried splitting up the file based on how I want to organize the data and store the data from each text file into a separate ArrayList but I had memory problems with that as well. I have also stored all of the data into one "master" ArrayList and then invoked a method on that "master" to add the data to the appropriate ArrayList (removing/clearing the data from the "master" as soon as it copied).
Any ideas on how to streamline and reduce memory impact?
EDIT**
Logcat:
That is from when you click the back button and then load the activity again. The following is just one of the messages produced (in verbose):
You can try adding android:largeHeap="true" in your manifest but it is not supported in Android API-8. To my understanding, you are reading and storing the data onto heap memory, which is usually quite limited and its size depends on the device your running your app on.
You might also want to investigate here: android - out of memory
First, make sure you don't have two copies of the data in memory. You can null out the reference to the old ArrayList before starting to create the new one, though you have to do that carefully -- calling ArrayList.clear() first would be more thorough.
Second, figure out how much memory that ArrayList is eating up by using a tool like hprof or Eclipse MAT. If it's using a ton of space, you may want to consider a more compact data representation.
So... from the code snippet, it looks like you're just reading a bunch of text strings in from a file, using a byte-to-char conversion. If the source material is plain UTF-8 (i.e. essentially ASCII), you've got a 2x expansion to UTF-16, plus allocation of the char[] object to hold it, plus the size of the String object that wraps that, plus the overhead of the entry in the ArrayList. Depending on how long an average string in the file is, this can be a significant multiple on your 1.8MB.
One way to avoid this would be to read the file into memory as byte[], scan it to figure out where each string starts, and just keep an array of integers with the start offset of each string. When you need string N, decode it from the byte[] into a String and return it. This reduces your overhead significantly. You could reduce it further by not loading the file and just reading individual strings out as needed (using a RandomAccessFile), but this may slow things down.
Seems to be you might have a bit of trouble with the immutability of Strings .
Why don't you try changing your code so you use StringBuilder for instance? Of course, you'll have to change more than one thing but it would be similar enough to your code and wouldn't fill your memory up as fast.
I am banging my head for the last couple days in order to get this done but Im unable to. Someone please help me out!
Let me not tell u the whole thing and will try to explain it simply n clearly.
Im having 1 ArrayList. I am trying to replicate that into another one and trying to delete an item at a particular index. But this not only deletes the item in the replicated ArrayList but also the original ArrayList.
For ex:
var DuplicateList:ArrayList = new ArrayList();
DuplicateList = OriginalList;
DuplicateList.removeItemAt(2);
The above not only deletes the "Item 3" at Index-2 in the DuplicateList but also in the OriginalList.
I just need some workaround with this approach as this is the only way by which whatever I typed inside the controls present in an ItemRenderer of a FLEX List control that uses the OriginalList as a dataProvider is RETAINED, when I change the dataProvider of the List Control from OriginalList to DuplicateList. The following approach does not retain all the data.
var DuplicateList:ArrayList = new ArrayList();
DuplicateList.addAll(OriginalList);
DuplicateList.removeItemAt(2);
ListCntrl.dataProvider = DuplicateList;
Thanks for your help in advance...
A very, very important thing to understand:
ActionScript3 uses references to objects. Because of that, the two variables in this line of code refer to the exact same instance of an ArrayList:
DuplicateList = OriginalList;
So, when you remove an item from one reference, it is gone from the next. If you want two separate instances of ArrayList, then you need to clone it like you are suggesting later in your code.
So far, so good... but why is your ListCntrl retaining the data from the OriginalList? That doesn't make any sense at all. If you remove an item from DuplicateList and then use it as the data provider, then that item shouldn't be there. I think there is more to this story...
I have a class called people that has its own name, id etc...
I have a full list of people in an array list public ArrayList<people> pList;
When I click on some names I want to add the people in pList to public ArrayList<people> followList; Doing followList.add(pList.get(position)) doesn't work. What is the proper way to do this.
Also, on another click I would like to remove the particular object from the followList so I tried doing followList.remove(pList.get(position)) but obviously it doesn't work as well.
Im basically trying to have a list of people from the original list.
The followList seems to be not initialized. You should call initialize it with new ArrayList<people>() before adding to or removing from it.
Are you sure that you have instantiated the ArrayList followList, and that there is in fact a element at pList[position]?
I've searched far and wide for this answer and can't seem to find it.
I'm looking to populate a very simple 3 line listview, no more then 5-6 words per line at the most inside of my android app.
I'm currently using a base adapter and a string array to enable the actual text to show up on the screen.
I want to have the ability to update the information inside of my listview remotely using
some sort of means whether that's xml, SQLite, plain text, etc and then have that hosted file populate my listview.
Can anyone here help me to figure out how to do this? I'm still pretty new to android development so please go easy on me. Hopefully this question wont be too hard answer and also not too difficult to enable for a newbie like myself.
If the most you're going to ever have in there is just 3 lines of text, I think a SQLite DB may be a bit much for your situation. I'd look into using a Typed Array.
Here's a link to the Android Dev Guide on this subject:
http://developer.android.com/guide/topics/resources/more-resources.html#TypedArray
Here's a code sample:
public class YourListActivity extends ListActivity {
String[] mTestArray;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Create an ArrayAdapter to contain your items
ArrayAdapter<String> adapter;
mTestArray = getResources().getStringArray(R.array.yourArray);
// Assign your array to an adapter with your layout file
adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, mTestArray);
// Assign the adapter to this ListActivity
setListAdapter(adapter);
}
}
EDIT
Just realized that your data will be on a remote server, so this approach may not work for you, but it can still give you an idea of how to take your data once received from your remote server and place it into a ListView.