Android: Can I use single InputStream for multi method? - android

I have some problem about using readline(). I have single inputStream it's from main class
private String url = "BoardLayoutSet/01_basic.templete";
private InputStream boardName = getResources().getAssets().open(url);
Board b = new Board(boardName);
And I send this "boardName" is InputStream to "Board" class. In this Board.class has constructor like this code below
public Board(InputStream boardName) throws IOException{
int[] d = LayoutDimensions(boardName); //<----First,use InputStream
....
......
build(null, boardName); //<<--Second,Use InputStream
}
First method is called by this constructor(Above).
First method it use "InputStream" like this(Below)
public int[] LayoutDimensions(InputStream boardName) throws IOException {
BufferedReader reader1 = new BufferedReader(new InputStreamReader(boardName));
L1 = reader1.readLine(); // #Basic
L1 = reader1.readLine(); // %Level 1
L1 = reader1.readLine(); // space line
L1 = reader1.readLine(); // First row of board
for (int i = 0; i < L1.length(); i++) {
if (L1.charAt(i) != ' ') {
x++;
}
}
System.out.println(L1);
System.out.println("Width(x):" + x);
// ////////////////
boardName.reset();
BufferedReader reader2 = new BufferedReader(new InputStreamReader(boardName));
L2 = reader2.readLine(); // #Basic
L2 = reader2.readLine(); // %Level 1
L2 = reader2.readLine(); // space line
L2 = reader2.readLine(); // First row of board
while (L2.length()!=0) {
System.out.println(L2.charAt(0));
y++;
L2 = reader2.readLine();
}
System.out.println("Height(y):" + y);
.....
......
reader1.close();
reader2.close();
reader3.close();
return dimensions;
}
When I use one method only .it can work. Next, I need to call Second method like this
protected void build(Random r1, InputStream boardName) throws IOException {
if (r1==null) {
long seed = new Random().nextLong();
r = new Random(seed);
} else {
r = r1;
}
tTile = new Tile[depth][height][width];
int x;
int y;
int z=-1;
BufferedReader buffer = new BufferedReader(new InputStreamReader(boardName));
String L=null;
buffer.reset();
L = buffer.readLine(); //Basic
.......
......
......
it's error since this line>> L=buffer.readLine();
I tried to swap order : use second method before fist method . the second can use but first method is error.
I think it's problem about Inputstream so I tried to make two Inputstream but it's not better.

It seem you already closed the input stream in the method LayoutDimensions.
This
reader1.close();

Related

Load textfiles to android app - Out of memory despite not heavy files

I cannot, by now, understand why I got an out-of-memory exception when I load 9 different textfiles into my android app. The total size of the textfiles is about 10 MB. And I hade to change to large-heapsize in the manifest file to be able to load these files. Its not a good solution, so I wonder if someone could help me to understand what causes the heapsize to rize over 100 MB.
Another thing, could be a clue of something??, is that when heapsize has climed a bit over 100 MB and allocated memory is sligtly below - all loading is done, something happends:
The garbagecollector makes something immediately when loading is finished - the allocated space falls dramatically from 100 MB to 35 MB.
SO I wonder - what is happening? Why is the loading so memory consuming?
I can say that I have a class called FileManager where all loading taking place.
And because FileManager do not extend Activity, I have to pass a context to this class.
Could it be the context that is memory consuming? I think It may be and I have to move the loading when the app starts app at first.
Here is the FileManager-class
public class FileManager {
private String[][] solarObj,, celestObj, stars, sun, moon, venus, march, jupiter, saturn;
private ArrayList <String[][]> stringObjects = new ArrayList <String[][]> () ;
private String[] textFile;
private Context context;
private AssetManager assetManager;
public FileManager(Context context) {
this.context = context;
assetManager = context.getResources().getAssets();
instanciateStrings();
putStringsToList();
initializeTextFile();
for (int array_index = 0; array_index < 9; array_index++) {
read(this.textFile[array_index], this.stringObjects.get(array_index).length, array_index);
//printString(array_index);
}
}
private void instanciateStrings() {
this.solarObj = new String[98][4];
this.celestObj = new String[7][3];
this.stars = new String[92][7];
this.sun = new String[14246][15];
this.moon = new String[14246][15];
this.venus = new String[14246][15];
this.march = new String[14246][15];
this.jupiter = new String[14246][15];
this.saturn = new String[14246][15];
}
/**
* Lägger in de tvådimensionella strängvektorerna i en arraylist.
*/
private void putStringsToList() {
this.stringObjects.add(this.celestObj);
this.stringObjects.add(this.solarObj);
this.stringObjects.add(this.stars);
this.stringObjects.add(this.sun);
this.stringObjects.add(this.moon);
this.stringObjects.add(this.venus);
this.stringObjects.add(this.march);
this.stringObjects.add(this.jupiter);
this.stringObjects.add(this.saturn);
}
/**
* Filnamnen läses in i en strängvektor
*/
private void initializeTextFile() {
this.textFile = new String[9];
this.textFile[0] = "celestobj_txt.txt";
this.textFile[1] = "solarObj_txt.txt";
this.textFile[2] = "stars_txt.txt";
this.textFile[3] = "sun_txt.txt";
this.textFile[4] = "moon_txt.txt";
this.textFile[5] = "venus_txt.txt";
this.textFile[6] = "march_txt.txt";
this.textFile[7] = "jupiter_txt.txt";
this.textFile[8] = "saturn_txt.txt";
}
private void read(String text_file, int len, int index) {
String[] stringBuffer = new String[len]; // temporär textsträng som read-objektet returnerar textraden till.
BufferedReader br;
try {
InputStream input = assetManager.open(text_file);
br = new BufferedReader(new InputStreamReader(input, "UTF-8"));
//bufferedReader = new BufferedReader(new InputStreamReader(getClass().getResourceAsStream(text_file)));
String line;
int i = 0;
while ( (line = br.readLine()) != null) {
stringBuffer[i] = line; // läs in rader från textfilen
i++;
}
br.close();
} catch (FileNotFoundException fnde) {
//fnde.printStackTrace();
System.out.println("filerna kunde inte hittas");
} catch (Exception e) {
e.printStackTrace();
}
splitString(stringBuffer, index);
}
private void splitString(String[] str, int index) {
int nCols = this.stringObjects.get(index)[0].length; // antal kolumner
for (int i = 0; i < str.length; i++) {
StringTokenizer st = new StringTokenizer(str[i]);
for (int j = 0; j < nCols; j++) {
this.stringObjects.get(index)[i][j] = st.nextToken();
}
}
}
since its 9 files that is to be loaded this read-method are called 9 times. Could this be the source to te memory leak?
Greatful for answer
EDIT: I choosed to show the whole class. Thanks again!!!
I think it's because of the String[] you are using to store read lines. Can you try it with a StringBuilder instead of String[] ?
// stringBuffer[i] = line;
stringBuilder.append(line);

I want to show the whole c program on screen in android

I wanted to show the whole c program on screen which should be visible to user.
I used textView but i am getting errors as the code contains special symbols.
for example:
android:text=" #include <stdio.h>
int main()
{
int x, y, temp;
printf("Enter the value of x and y\n");
scanf("%d%d", &x, &y);
printf("Before Swapping\nx = %d\ny = %d\n",x,y);
temp = x;
x = y;
y = temp;
printf("After Swapping\nx = %d\ny = %d\n",x,y);
return 0;
}" />
I also want that the user should be able to scroll the code as the codes may be larger than the example.I am a noob so please suggest me any alternate for the textView to display the code.
Save your C code in a file in assets folder, for example "res/assets/code.c".
Write a function that reads the content of a file to a String:
private String readFileInAssetsDir(String filename) {
BufferedReader br = null;
StringBuffer sb = new StringBuffer();
try {
br = new BufferedReader(new InputStreamReader(getAssets().open(filename)));
String line;
while((line = br.readLine()) != null)
sb.append(line + "\n");
} catch(Exception e) {
// TODO
}
return sb.toString();
}
And now define a WebView (not a TextView) in your layout (the advantages are that you can show any character, and WebView provides zoom and scroll directly):
<WebView
android:id="#+id/webView"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1" />
And finally I would enclose all C code in a <pre></pre> tag and then show it inside the WebView widget:
String plainCode = readFileInAssetsDir("code.c");
String htmlCode = "<pre>" + plainCode + "</pre>";
webView.loadDataWithBaseURL("", htmlCode, "text/html", "utf-8", "");
EDIT: THIS WORKS BUT READS ONLY A SINGLE LINE OF THE TEXT IN THE TXT FILE
String line;
TextView view;
#Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_addingprogrammultipletimes);
AssetManager am = getAssets();
try {
InputStream is = am.open("add.txt");
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
line = reader.readLine();
view = (TextView) findViewById(R.id.textView);
view.setText(line);
} catch (Exception e) {
e.printStackTrace();
}
}

How to convert ArrayList<String> to Float[]

I have to retrieve some data from a file to show it in a chart. The function that shows the chart requires he data as float[] whereas the retrieved data is in the form ArrayList<String>.
What is the easiest way to convert ArrayList<String> to float[]?
try {
FileInputStream fIn = context.openFileInput(fileDir+fileName);
InputStreamReader ipsr = new InputStreamReader(fIn);
BufferedReader b = new BufferedReader(ipsr);
ArrayList<String> list_prix = new ArrayList<String>();
String ligne;
while ((ligne = b.readLine()) != null) {
String dtVal = ligne.split(" ")[2];
dtVal = dtVal.substring(0, dtVal.length() - 2);
list_prix.add(dtVal);
}
//just here if i can convert list_prix to float[]
fIn.close();
ipsr.close();
}
catch (Exception e)
{
Log.e("blah", "Exception", e);
}
Thank you for your help.
I think the following will do it using Guava...
Collection<Float> floats = Collections2.transform(list_prix, new Function<String, Float>() {
public Float apply(String input) {
return Float.parseFloat(input);
}
});
Float[] floatArray = new Float[floats.size()];
floats.toArray(floatArray);
You can loop and use Float.parseFloat().
float [] floatValues = new float[list_prix.size()];
for (int i = 0; i < list_prix.size(); i++) {
floatValues[i] = Float.parseFloat(list_prix.get(i));
}
Now, this assumes that every string in your ArrayList can actually be parsed into a float. If not, it could throw an exception, so you may want to do this in a try/catch block if you are not sure.

Android CSV parser problem

I am having an issue while parsing a CSV file. It is only 2 rows of data with a comma separating them. Row one is a date and row 2 is a value. The date field will always have dates in it but sometimes the value is blank (or null?). When it gets to the null value I get a StringIndexOutOfBoundsException and the app crashes. I am logging each loop and can see the data but as soon as I get to a null value it stops looping and gives the error. If there are no null values then it works perfect. Here is my code:
BufferedReader buf = new BufferedReader(new StringReader(file));
String line = null;
while ((line = buf.readLine()) != null) {
try {
String date = null, value = null;
String[] RowData = line.split(",");
date = RowData[0];
value = RowData[1]; (this is the row it crashes on)
This is what the CSV looks like:
2011-08-28 09:16,8.23
2011-08-28 09:15,8.24
2011-08-28 09:14,8.26
2011-08-28 09:13,8.34
2011-08-28 09:12,
2011-08-28 09:11,10.72
2011-08-28 09:10,
2011-08-28 09:09,
the value at 09:13 is the last thing in logcat before I get the error.
This fixed it:
if(RowData.length == 2) {
date = RowData[0];
value = RowData[1];
} else {
date = RowData[0];
value = "0";
}
I wrote a 0 in the value field so later processes will not choke on the null value. Thanks for all your help guys!
You want to do this or something like it:
String date = null, value = null;
String[] RowData = line.split(",");
date = RowData[0];
if(RowData.length ==2)value = RowData[1]; (this is the row it crashes on)
Or some variation of it e.g. if(RowData.length < 2) dont attempt to read the value. Its a pretty standard thing - if you ask an array for an index of a value it doesn't have Java will crash.
Why write your own CSV parsing when you could use a library that has already been written which will do it for you? Perhaps OpenCSV would help you achieve your CSV parsing goal.
Check the length of RowData before you try to access it. It looks like split() is returning an array with a single object but you're trying to access the second object, which is indeed out of bounds.
public class CityParser {
DocumentBuilderFactory factory;
DocumentBuilder builder;
Document doc;
Element ele;
int mediaThumbnailCount;`enter code here`
boolean urlflag;
CityListBean objBean = null;
Vector<CityListBean> vecCityList;
public CityParser() {
}
public Vector<CityListBean> getCityData() {
vecCityList = new Vector<CityListBean>();
try {
HttpClient httpClient = new DefaultHttpClient();
HttpContext localContext = new BasicHttpContext();
HttpGet httpGet = new HttpGet(
"http://heresmyparty.com/cms/index.php?option=com_chronocontact&chronoformname=add_event_form_download");
HttpResponse response = httpClient.execute(httpGet, localContext);
// String result = "";
BufferedReader reader = new BufferedReader(new InputStreamReader(
response.getEntity().getContent()));
CSVReader csvreader = new CSVReader(reader);
String[] nextLine;
while ((nextLine = csvreader.readNext()) != null) {
CityListBean objcitylist = new CityListBean();
// nextLine[] is an array of values from the line
objcitylist.setText_title(nextLine[5]);
objcitylist.setText_host(nextLine[6]);
objcitylist.setText_price(nextLine[7]);
objcitylist.setDate(nextLine[8]);
objcitylist.setText_venue(nextLine[11]);
objcitylist.setAddress(nextLine[12]);
objcitylist.setLatitude(nextLine[13]);
objcitylist.setLongitude(nextLine[14]);
objcitylist.setFile(nextLine[15]);
objcitylist.setText_description(nextLine[16]);
objcitylist.setCity(nextLine[17]);
vecCityList.addElement(objcitylist);
}
/*for (int i = 0; i < vecCityList.size(); i++) { CityListBean
objcity = (CityListBean) vecCityList.get(i);
System.out.println("Cf_id : " + objcity.getCityName());
System.out.println("-----------------------------------"); }*/
} catch (Exception ex) {
ex.printStackTrace();
}
return vecCityList;
}
}
==========================================================================================
public class CSVReader {
private BufferedReader br;
private boolean hasNext = true;
private char separator;
private char quotechar;
private int skipLines;
private boolean linesSkiped;
public static final char DEFAULT_SEPARATOR = ',';
public static final char DEFAULT_QUOTE_CHARACTER = '"';
public static final int DEFAULT_SKIP_LINES = 0;
public CSVReader(Reader reader) {
this(reader, DEFAULT_SEPARATOR, DEFAULT_QUOTE_CHARACTER,
DEFAULT_SKIP_LINES);
}
public CSVReader(Reader reader, char separator, char quotechar, int line) {
this.br = new BufferedReader(reader);
this.separator = separator;
this.quotechar = quotechar;
this.skipLines = line;
}
public String[] readNext() throws IOException {
String nextLine = getNextLine();
return hasNext ? parseLine(nextLine) : null;
}
private String getNextLine() throws IOException {
if (!this.linesSkiped) {
for (int i = 0; i < skipLines; i++) {
br.readLine();
}
this.linesSkiped = true;
}
String nextLine = br.readLine();
if (nextLine == null) {
hasNext = false;
}
return hasNext ? nextLine : null;
}
private String[] parseLine(String nextLine) throws IOException {
if (nextLine == null) {
return null;
}
List<String> tokensOnThisLine = new ArrayList<String>();
StringBuffer sb = new StringBuffer();
boolean inQuotes = false;
do {
if (inQuotes) {
// continuing a quoted section, reappend newline
sb.append("\n");
nextLine = getNextLine();
if (nextLine == null)
break;
}
for (int i = 0; i < nextLine.length(); i++) {
char c = nextLine.charAt(i);
if (c == quotechar) {
// this gets complex... the quote may end a quoted block, or escape another quote.
// do a 1-char lookahead:
if( inQuotes // we are in quotes, therefore there can be escaped quotes in here.
&& nextLine.length() > (i+1) // there is indeed another character to check.
&& nextLine.charAt(i+1) == quotechar ){ // ..and that char. is a quote also.
// we have two quote chars in a row == one quote char, so consume them both and
// put one on the token. we do *not* exit the quoted text.
sb.append(nextLine.charAt(i+1));
i++;
}else{
inQuotes = !inQuotes;
// the tricky case of an embedded quote in the middle: a,bc"d"ef,g
if(i>2 //not on the begining of the line
&& nextLine.charAt(i-1) != this.separator //not at the begining of an escape sequence
&& nextLine.length()>(i+1) &&
nextLine.charAt(i+1) != this.separator //not at the end of an escape sequence
){
sb.append(c);
}
}
} else if (c == separator && !inQuotes) {
tokensOnThisLine.add(sb.toString());
sb = new StringBuffer(); // start work on next token
} else {
sb.append(c);
}
}
} while (inQuotes);
tokensOnThisLine.add(sb.toString());
return (String[]) tokensOnThisLine.toArray(new String[0]);
}
public void close() throws IOException{
br.close();
}
}
Have you tried to check first
if (RowData[1]!=null) or possibly if (RowData[1]!="")
I don't see why that would cause your app to crash though,
it should just set value to null or ""

I'm not understanding the following code

I have to understand this code to create my own app(almost based on this function):
public static String[][] ReadFilePerLine(Context context, String nom) {
int i = 0;
try {
FileInputStream fIn = context.openFileInput(nom);
InputStreamReader ipsr = new InputStreamReader(fIn);
BufferedReader b = new BufferedReader(ipsr);
i = getLineNumber(context, nom);
String[][] s = new String[2][i/2];
i = 0;
String ligne;
int j = 0;
while ((ligne = b.readLine()) != null) {
if (i % 2 == 0)
s[0][j] = ligne;
else {
s[1][j] = ligne;
j++;
}
i++;
}
fIn.close();
ipsr.close();
return s;
}
catch (Exception e)
{}
I'm not understanding why the using of a 2D array? and with two rows ?(String[][] s = new String[2][i/2];)
here is the data that it will be stored in the file:
data = date + " : " + y + "L/100KM"+ " " + value1 + "L "+ value2 + "KM\n";
Necessary functions:
public void updatelv(Activity activity) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
String fileName = getResources().getString(R.string.fileName);
fileDir = "" + preferences.getString("login", "") + "."+ preferences.getString("marque", "") + ".";
s = myIO.ReadFilePerLine(getApplicationContext(), fileDir+fileName);
ListView L = (ListView) findViewById(R.id.lv);
L.setAdapter(new ArrayAdapter<String>(this, R.layout.list_item, s[0]));
for (int i = 0; i< s[0].length; i++) {
Log.d("Saves",s[0][i]);
}
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.histo);
context = getApplicationContext();
activity = this;
final SharedPreferences preferences = PreferenceManager
.getDefaultSharedPreferences(context);
String fileName = getResources().getString(R.string.fileName);
fileDir = "" + preferences.getString("login", "") + "."+ preferences.getString("marque", "") + ".";
s = myIO.ReadFilePerLine(getApplicationContext(), fileDir + fileName);
updatelv(this);
ListView L = (ListView) findViewById(R.id.lv);
L.setTextFilterEnabled(true);
L.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// When clicked, show a toast with the TextView text
String tmp = s[1][position];
if (tmp == null)
tmp = "Aucun fichier trouvé!";
Toast.makeText(getApplicationContext(), tmp, Toast.LENGTH_SHORT)
.show();
}
});
ReadFilePerLine function:
public static String[][] ReadFilePerLine(Context context, String nom) {
int i = 0;
try {
FileInputStream fIn = context.openFileInput(nom);
InputStreamReader ipsr = new InputStreamReader(fIn);
BufferedReader b = new BufferedReader(ipsr);
i = getLineNumber(context, nom);
String[][] s = new String[2][i/2];
i = 0;
String ligne;
int j = 0;
while ((ligne = b.readLine()) != null) {
if (i % 2 == 0)
s[0][j] = ligne;
else {
s[1][j] = ligne;
j++;
}
i++;
}
fIn.close();
ipsr.close();
return s;
}
catch (Exception e)
{
}
Thank you for you help.
The code is clearly reading from a file whose format consists of pairs of lines; it puts the first line of each pair in s[0][...] and the second line of each pair in s[1][...]. If your format doesn't have that peculiarity -- which it doesn't sound as if it does -- then you don't need to do that. Just make an ordinary 1-dimensional array of Strings.
It appears that what they are doing is breaking the file down into two lists (or String arrays, in this case), one which contains all the even-numbered lines, and one which contains all the odd-numbered lines. I'll comment up the code for you:
public static String[][] ReadFilePerLine(Context context, String nom) {
int i = 0;
try {
//open the specified input file and create a reader
FileInputStream fIn = context.openFileInput(nom);
InputStreamReader ipsr = new InputStreamReader(fIn);
BufferedReader b = new BufferedReader(ipsr);
//get the total number of lines in the file, and allocate
//a buffer large enough to hold them all
i = getLineNumber(context, nom);
String[][] s = new String[2][i/2];
i = 0; //set the current line to 0
String ligne;
int j = 0; //set the section index to 0
//now read through the lines in the file, and place every
//even-numbered line in the first section ('s[0]'), and every
//odd-numbered line in the second section ('s[1]')
while ((ligne = b.readLine()) != null) {
if (i % 2 == 0)
//even-numbered line, it goes into the first section
s[0][j] = ligne;
else {
//odd-numbered line, it goes into the second section
s[1][j] = ligne;
j++; //increment the section index
}
i++; //increment the line count
}
//done, cleanup and return
fIn.close();
ipsr.close();
return s;
}
catch (Exception e) {
//should at least log an error here...
}
}
As to why they chose to use a String[][], I cannot say. Probably for convenience, since they want a single object that they can return from this function that contains both lists. Personally I would use a Map that has two List instances in it, but the String[][] works just as well and is probably marginally more efficient.
Judging from your example data it does not appear that you need to use this format. But if you want to use it, you need to structure your data so that the key is on one line, and its associated value is on the next, like:
date
2011-03-19
userName
someGuy
it seems to read from a file, split it into the two dimensional array (based on row count).
Why it does it? I have no idea why you'd want that. Check out the function that it returns s to and find out!

Categories

Resources