I've read about one trillion answers to this question that don't involve using a vector of strings. I need a function that will read words from a text file one by one into a data structure that I can call later on. Or, I need a function that can read words from a text file one by one and store them in three separate lists in one data structure.
private Vector<String> getLetters(String chapter, int t) throws IOException {
InputStream is = getResources().openRawResource(com.example.android.myprojecte.R.raw.aa);
Vector<String> letters = null;
InputStreamReader isReaded = new InputStreamReader(is);
BufferedReader reader = new BufferedReader(isReaded);
String line = null;
while ((line = reader.readLine()) != null) {
letters.add(line);
}
return letters;
}
Basically, I just need to read a text file into a vector string, but my emulator keeps crashing. It could be something with my fragments, but the error code is signifying it's an I/O problem? So is this wrong above please and thank you
edit: i am pretty sure that the error is a null pointer exception
edit2: i restarted eclipse and i have a ton of errors in other parts of my code... i think this part is fine.
answer: I created a new blank project, added is.close() and br.close() statements, and declared the variable inside a different function since i had no idea what i was doing. Not sure which of these worked but declaring right after main activity didn't work like the guy suggested below
You need to allocate letters. letters = new Vector<String>();
Block Array or multidimensional array Variables. For some reason my app is throwing out of memory on my loading of my pub vars class. This started happening when I started using Block Arrays. It works on actual devices but not on the emulators. Any thoughts? Should I set my block arrays to actual needs?
Current Block Arrays:
public static String[][] Name = new String[1000][1000];
however I only use maybe 10 or so. Is the device allocating space for the potential of the 1000 and is that why it is errors out? If so, how can I use these as the need may grow and I do not want to put a small limit on it. Thanks in advance for any thoughts.
With
public static String[][] Name = new String[1000][1000];
you are allocating 1 million strings (1000x1000) which is quite a bunch. If the information on this page is correct each string at least takes 40 bytes, so that would be around 39 Mbytes in your case and this can easily be too much memory on the heap for 1 activity. I would start there to refactor if you are only using 10. There is probably a better solution than your approach but without any more details on your code it's hard to give them. But of the top of my head, why not use a Set<String> or List<String> ?
Edit: So it's seems to me that you just want a Collection that scales dynamically. For that array is not the best choice. There are many of datatypes for that but one simple example whould be an ArrayList which also uses a array as backing datatype but by default will be instanciated with a capacity of 10 and expands dynamically if you continue to add elements
List<String> stringList = new ArrayList<String>();
stringList.add("string1");
stringList.add("string2");
...
If you want each element to have its own list of strings just create an object for that:
public class CompoundString {
private String key;
private List<String> stringList;
...
}
and use it like this
List<CompoundString> compoundStringList = new ArrayList<CompoundString>();
compoundStringList.add(new CompoundString("string1", new ArrayList<String>());
or just use a map:
Map<String,List<String>> stringMap = new HashMap<String,List<String>>();
stringMap.put("string1", new ArrayList<String>());
This is pretty basic concept in most programming languages and I would start to read some docs about the various collections:
http://docs.oracle.com/javase/7/docs/api/java/util/List.html
http://docs.oracle.com/javase/7/docs/api/java/util/Set.html
http://docs.oracle.com/javase/7/docs/api/java/util/Map.html
http://www.mkyong.com/java/what-is-the-different-between-set-and-list/
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.
I have a ListView in my app, and I've over-ridden the getView() method so I can change the row's ImageView src depending on the row's text.
The problem is, I've noticed the ListView scrolling is lagging, and when I check DDMS, it seems the Garbage Collector is being called everytime the ListView is being scrolled, thus slowing the scrolling.
I've also noticed the Garbage Collector being called in a different part of my app, when reading lines from a BufferedReader, which makes opening a 2,000 line file take ~47 seconds, where as a file exporer I have installed on my phone opens that same file in about 2 seconds.
So my question is, what could be causing the constant Garbage Collection every 200ms or so, and how do I prevent it? It's really slowing my app down and I fear it will put some users off if I don't solve it.
Thanks,
Alex.
ListView getView():
class IconicAdapter extends ArrayAdapter<String> {
IconicAdapter(){
super(FileBrowser.this, R.layout.filebrowser_listview_row, R.id.listtext, directoryEntries);
}
#Override
public View getView(int position, View convertView, ViewGroup parent){
View row = super.getView(position, convertView, parent);
TextView text = (TextView) row.findViewById(R.id.listtext);
ImageView icon = (ImageView) row.findViewById(R.id.listicon);
entryFullFileName = directoryEntries.get(position).toString();
if(entryFullFileName.contains(".") && !entryFullFileName.matches("^\\.+$")){
String[] parts = entryFullFileName.split("\\.");
lastIndex = parts.length - 1;
fileType = parts[lastIndex];
}else{
fileType = "";
}
if(fileIsDir.get(position) == true){
icon.setImageResource(R.drawable.folderlightblue);
}else if(fileType.equals("html")){
icon.setImageResource(R.drawable.filehtml);
}else if(fileType.equals("css")){
icon.setImageResource(R.drawable.filecss);
}else if(fileType.equals("js")){
icon.setImageResource(R.drawable.filejs);
}else if(fileIsDir.get(position) == false){
icon.setImageResource(R.drawable.fileplain);
}
return(row);
}
}
Code To Open File
I removed the code the other day that logged how many seconds it took to open the file, but it took 47 seconds and definitely took too long, and again while the while loop is doing it's thing, there's constant calls to the Garbage Collector, which I'm guessing in the cause of the slow file reading - and yes, this function is called in a thread with progressDialog showing while the file is being read
private String getLocalFileContents(String fileUri){
try{
String contents = "";
BufferedReader in = new BufferedReader(new FileReader(fileUri));
String line;
while((line = in.readLine()) != null){
contents += line + "\n";
}
in.close();
return contents;
}catch(Exception e){
toast.setText("Failed to open sdcard file, try again.");
}
return null;
}
UPDATE:
The file reading problem is solved, turns out the String concatenation made the Garbage Collector get called after each loop, dramatically slowing the file reading down. As suggested by an answer I used StringBuilder instead and it now opens in a second - hooray!
2ND UPDATE:
I know what the cause of the constant GC calls when scrolling my ListView is, it's the ListView attribute android:cacheColorHint="#android:color/transparent" - but I don't know a work-around!
In general, garbage collection is happening because you're creating too many objects unnecessarily. It'd be easier to help with your code, but I'll give it a shot anyway.
In the case of your list, you're probably recreating your view in every call to getView. You should instead re-use convertView when appropriate. See my answer to this other SO question for an idea of how to structure your getView method.
Your file reading problem is a bit harder to guess at, but 47s seems ridiculously long for 2,000 lines. Are you also creating objects in that loop?
Update:
So apparently your problem isn't really with your View objects themselves, but it's all the work you do every time you get a View. You're doing quite a bit of work every time: a RegEx match, string splitting (and associated string object creation), etc. You should at minimum cache the results of this so that you don't have to redo the work for each item every time it comes back into view.
One optimization would be to stop splitting the entire string to get the filetype. You could use something like
String fileType = "";
int lastDot = entryFullFileName.lastIndexOf(".");
if(lastDot!=-1) {
fileType = entryFullFileName.substring()
}
That certainly shouldn't take 47s though.
Look at EfficientAdapter here is link
And explained more about efficient adapter and getView method in other thread have a look at it, here is link
Hope this help!!!
Yes, android:cacheColorHint="#android:color/transparent" is causing excessive calling of the garbage collector on some OS versions (not sure if the newest ones this is fixed).
Well, just try to not use it. For example, I spoke with my designers, explained them the problem about the cause of the lags, and they agreed to not use the transparent background.
I am displaying search results from a webservice.
What I do is OnCreate I hit the webservice display records, as android supports multitasking. If user opens another screen and after some time comes back to the search results page, the application starts acting crazy....
OnCreate method I load data some thing like :
private void loadData() throws Throwable{
try {
jsonArray = JSONService.getJsonArray(getResources().getString(R.string.catJson));
} catch (Throwable e) {
Log.e(TAG, e.getMessage());
throw e;
}
}
and then I iterate through json array and change labels value to display result on the screen.
Any ideas how to fix this?
Yes, please explain our problem better. Are you familiar with the Activity life-cycle? There are several different callbacks that you must manage in order for your concept of multitasking to actually work. Based on the limited info you've provided, I don't think you're saving any of your application state when your Activity loses focus. So your process may be getting shutdown and when you come back, your JSON array is gone. Read this:
http://developer.android.com/guide/topics/fundamentals.html#lcycles
Are you calling the super in your OnCreate?
super.onCreate(savedInstanceState);