Reputation: 341
I am trying to apply a tutorial on a basic app i am building as a method to learn Android Studio, and part of what i am doing is having a new window ( activity ) with a ListView to view information saved in a CSV file. When i load the main app, it is fine, but when i click on the button that suppose to take me to the new window where the List view is to show the CSV content, the app stops ( shut down ).
Attached, a screen shot of the project layout, and the window where the ListView is.
Following are the codes;
This is the code from the class where the code of the ListView is written, the class name is LogerView, and there is a button at the MainActivity class, the main window for the app, that would call the LogerView;
public class LogerView extends AppCompatActivity {
CSVAdapter mAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.viewer);
ListView mList = (ListView) findViewById(R.id.mList);
mAdapter = new CSVAdapter(this, -1);
mList.setAdapter(mAdapter);
mList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View v, int pos, long id) {
Toast.makeText(v.getContext(), mAdapter.getItem(pos).getListCode(), Toast.LENGTH_SHORT).show();
}
}
);
}
public void toasting(String msg) {
Toast.makeText(LogerView.this, msg, Toast.LENGTH_SHORT).show();
}
public void switchToMain(View v) {
Intent MainActivity = new Intent(this, MainActivity.class);
startActivity(MainActivity);
}
}
This is the Code in the CSVAdapter :
public class CSVAdapter extends ArrayAdapter<fileView>{
Context ctx;
public CSVAdapter(Context context, int textViewResourceId) {
super(context, textViewResourceId);
this.ctx = context;
loadArrayFromFile();
}
@Override
public View getView(final int pos, View convertView, final ViewGroup parent){
TextView mView = (TextView)convertView;
if(null == mView){
mView = new TextView(parent.getContext());
mView.setTextSize(15);
}
mView.setText(getItem(pos).getListCode());
mView.setText(getItem(pos).getListNumber());
mView.setText(getItem(pos).getListRadio());
mView.setText(getItem(pos).getListCheckBox());
mView.setText(getItem(pos).getListNoteText());
mView.setText(getItem(pos).getListTime());
return mView;
}
private void loadArrayFromFile(){
try {
String FILENAME = "entry_log.csv";
InputStream is = ctx.openFileInput(FILENAME);
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
String line;
while ((line = reader.readLine()) != null) {
String[] RowData = line.split("/");
if (RowData.length < 6) {
Log.e("SOME_TAG", "Invalid or empty line! . . .");
continue;
} else {
fileView cur = new fileView();
cur.setListCode(RowData[0]);
cur.setListNumber(RowData[1]);
cur.setListRadio(RowData[2]);
cur.setListCheckBox(RowData[3]);
cur.setListNoteText(RowData[4]);
cur.setListTime(RowData[5]);
this.add(cur);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
I renamed the PltInfo class to fileView, and the Code is:
package net.testerapp.loger;
public class fileView {
private String listCode, listNumber, listRadio, listCheckBox, listNoteText, listTime;
public String getListCode() {
return listCode;
}
public void setListCode(String listCode) {
this.listCode = listCode;
}
public String getListNumber() {
return listNumber;
}
public void setListNumber(String listNumber) {
this.listNumber = listNumber;
}
public String getListRadio() {
return listRadio;
}
public void setListRadio(String listRadio) {
this.listRadio = listRadio;
}
public String getListCheckBox() {
return listCheckBox;
}
public void setListCheckBox(String listCheckBox) {
this.listCheckBox = listCheckBox;
}
public String getListNoteText() {
return listNoteText;
}
public void setListNoteText(String listNoteText) {
this.listNoteText = listNoteText;
}
public String getListTime() {
return listTime;
}
public void setListTime(String listTime) {
this.listTime = listTime;
}
}
The MainActivity Code is as following, and so far this one operate in a perfect way, saving info, clearing text, but when clicked on the view Button which should switch to the PltInfo class to display the ListView, is where the app shut down. ( NO CHANGES TO THIS CODE )*
My CSV file is not located in an Assets folder as the tutorial, i view it through Android Device Monitor on this path emulator/data/data/net.testerapp.loger/files/entry_log.csv
so i created a string FILENAME = entry_log.csv; and placed it in the code after InputStream is = ctx.openFileInput(FILENAME);
not sure if this is the problem and how to solve it ? Plus the ListView layout, is not well organized in a way where it would show all the items, i just wanted to first test it, by showing the first item as in the tutorial but did not lunch the window at all in order to go from there reorganizing the layout of the List ... any guidance on how to fix that too will be appreciated. The link to the tutorial is : https://www.youtube.com/watch?v=S8_HnA7aLd0
** Canceld the logcat entry since i am not getting an error now
[![enter image description here][2]][2]
[![enter image description here][3]][3]
Well, i went over the steps in the Tutorial and i redid it, this time i did not get any Error, but still no response from the app, i was apple to switch to the next window activity from the MainActivity after hitting the view button, but then in hte second window, i get an empty space, without the List, i made sure the list in the layout, and the id of the list match what is in the code but not sure why it is not applying the code !?
I edited the code in the main post, to what i have right now, and attached the current screen shots of the app.
One last thing this is the viewer layout .xml file :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:layout_width="wrap_content"
android:layout_height="235dp"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:id="@+id/mList" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="View File"
android:id="@+id/ViewFileBtn"
android:layout_marginTop="60dp"
android:layout_gravity="center"
android:onClick="ViewFile" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Back"
android:id="@+id/BackBtn"
android:layout_gravity="center|bottom"
android:onClick="switchToMain" />
</LinearLayout>
[enter image description here][4]
I am trying to understand the problem here, and awaiting some help, here are some screen shots i took running the debugger, which i am not really familiar with, thus kind of lost trying to understand the threads.
[![enter image description here][5]][5] [enter image description here][6]
Upvotes: 0
Views: 1028
Reputation: 341
So, Problem solved, and the CODE is sound ... the file had to be uploaded again, and the if statement as @Yazan mentioned really helped ... Thanks to Freenode #android-dev and a Heor *** Zharf ** who insisted i learn how to use the Debugger and followed with me through the problem it is clear.
Must admit, the outcome of the listview is not what expected, i just need to go over the layout and figure out what is the problem with it.
Upvotes: 0
Reputation: 10971
I believe the reason for the crash is that you are executing loadArrayFromFile on the main thread, this is a long running process as it involves opening and reading a file. try wrapping loadArrayFromFile in an AsyncTask and it's better to move it out of the Adapter class.
**
EDIT
** You can implement the AsyncTask like this:
private class OpenFileTask extends AsyncTask<Void, Void, ArrayList<PltInfo>> {
protected Long doInBackground(Void... params) {
ArrayList<PltInfo> data=loadArrayFromFile();
return data;
}
private void loadArrayFromFile(){
try {
ArrayList<PltInfo>data=new ArrayList<PltInfo>();
// Get input stream and Buffered Reader for our data file.
String FILENAME = "entry_log.csv";
InputStream is = ctx.openFileInput(FILENAME);
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
String line;
//Read each line
while ((line = reader.readLine()) != null) {
//Split to separate the name from the capital
String[] RowData = line.split(",");
//Create a State object for this row's data.
PltInfo cur = new PltInfo();
cur.setEntryCode(RowData[0]);
cur.setEntryNum(RowData[1]);
cur.setSelected(RowData[2]);
cur.setCheckBoxText(RowData[3]);
cur.setNoteText(RowData[4]);
cur.setGetNow(RowData[5]);
//Add the State object to the ArrayList (in this case we are the ArrayList).
data.add(cur);
}
return data;
} catch (IOException e) {
e.printStackTrace();
}
}
protected void onPostExecute(ArrayList<PltInfo> result) {
if(result!=null){
}
}
}
Then pass the data to your adapter like this:
private ArrayList<PltInfo>mData;
public CSVAdapter(Context context, int textViewResourceId,ArrayList<PltInfo> data) {
super(context, textViewResourceId);
//Store a reference to the Context so we can use it to load a file from Assets.
this.ctx = context;
mData=data;
}
then call the async task from your activity like this:
OpenFileTask task=new OpenFileTask();
task.execute();
Upvotes: 0
Reputation: 6082
from the exception:
Caused by: java.lang.ArrayIndexOutOfBoundsException: length=1; index=1 at net.testerapp.loger.CSVAdapter.loadArrayFromFile(CSVAdapter.java:103)
it says you are trying to read array item at index 1, while the array does not have an item in that position i.e: the array length is shorter than the position you are trying to read.
to avoid this, check the RowData
length before creating the object of PltInfo
in method loadArrayFromFile()
:
while ((line = reader.readLine()) != null) {
//Split to separate the name from the capital
String[] RowData = line.split(",");
if(RowData.legth<6){
Log.e("SOME_TAG","invalid or empty line! skipping...");
continue;
}else{
//Create a State object for this row's data.
PltInfo cur = new PltInfo();
cur.setEntryCode(RowData[0]);
cur.setEntryNum(RowData[1]);
cur.setSelected(RowData[2]);
cur.setCheckBoxText(RowData[3]);
cur.setNoteText(RowData[4]);
cur.setGetNow(RowData[5]);
//Add the State object to the ArrayList (in this case we are the ArrayList).
this.add(cur);
}
}
Upvotes: 1