discodowney
discodowney

Reputation: 1507

Android - my listview is taking a few seconds to populate

So I have an activity that has a list view. This list is a list of all files in a specific folder. The files are routes a user has taken. What I want is to get the first and end point and then show the address of them in the list view item.

Ive got this working, my problem is that it is taking between 3-5 seconds to populate the view after I open the activity.

So I have a custom adapter for my list view. I have made an Async Task to handle reading the GeoPoints and then turning them into addresses to be displayed. It must be here that it is taking a while. It might just be that this process takes a couple of seconds. But there are only 4 files in the folder so taking that long just seems wrong to me.

I will attach my code for all the classes I use in this. If anyone notices something wrong, or has an idea without going through the classes, please let me know. Any help is really appreciated:

RouteListItem.java

public class RouteItem {

private String startPoint;
private String endPoint;
private double distance;

public RouteItem(String startPoint, String endPoint, double distance)
{
    this.startPoint = startPoint;
    this.endPoint = endPoint;
    this.distance = distance;
}

public String getStartPoint() {
    return startPoint;
}

public void setStartPoint(String startPoint) {
    this.startPoint = startPoint;
}

public String getEndPoint() {
    return endPoint;
}

public void setEndPoint(String endPoint) {
    this.endPoint = endPoint;
}

public double getDistance() {
    return distance;
}

public void setDistance(double distance) {
    this.distance = distance;
}
}

RouteListAdapter.java

public class RouteListAdapter extends ArrayAdapter<RouteItem> {

ArrayList<RouteItem> itemsList;
ArrayList<String> routeFiles;

public RouteListAdapter(Context context, int resource) {
    super(context, resource);

    itemsList = new ArrayList<RouteItem>();
}

public int getCount()
{
    return itemsList.size();
}

public void setItemList(ArrayList<RouteItem> routes)
{
    itemsList = routes;
}

@Override
public View getView(int position, View convertView, ViewGroup parent)
{
    RouteItem item = itemsList.get(position);
    ItemViewHolder viewHolder;

    if(convertView == null)
    {
        convertView = LayoutInflater.from(getContext()).inflate(R.layout.route_list_item, parent, false);
        viewHolder = new ItemViewHolder(convertView);
        convertView.setTag(viewHolder);
    }
    else
        viewHolder = (ItemViewHolder) convertView.getTag();

    viewHolder.startPtView.setText(itemsList.get(position).getStartPoint());

    viewHolder.endPtView.setText(itemsList.get(position).getEndPoint());

    viewHolder.distance.setText(String.valueOf(item.getDistance()));

    return convertView;
}

private static class ItemViewHolder
{
    public TextView startPtView, endPtView, distance;

    public ItemViewHolder(View listItem)
    {
        startPtView = (TextView) listItem.findViewById(R.id.startLocation);
        endPtView = (TextView) listItem.findViewById(R.id.endLocation);
        distance = (TextView) listItem.findViewById(R.id.distance);
    }
}
}

RouteLocationsTask.java

public class RouteLocationsTask extends AsyncTask<Void, Void, ArrayList<RouteItem>>{

private RouteListAdapter adapter;
private ArrayList<RouteItem> itemsList;
private ArrayList<String> routeFiles;
private Context context;

public RouteLocationsTask(RouteListAdapter adapter, ArrayList<String> routeFiles, Context context)
{
    this.adapter = adapter;
    itemsList = new ArrayList<RouteItem>();
    this.routeFiles = routeFiles;
    this.context = context;
}

@Override
protected ArrayList<RouteItem> doInBackground(Void... params) {
    for (int i = 0; i < routeFiles.size(); i++) {

        File loadFile = new File(Environment.getExternalStorageDirectory()+"/LocationTracker/Routes/"+routeFiles.get(i));
        try {
            BufferedReader br = new BufferedReader(new FileReader(loadFile));

            //while ((line = br.readLine()) != null) {
            String firstEntry = br.readLine();
            GeoPoint startPt = getGeoPointFromString(firstEntry);

            String lastEntry = tail(loadFile);
            GeoPoint endPt = getGeoPointFromString(lastEntry);

            Geocoder geocoder = new Geocoder(context, Locale.getDefault());
            List<Address> addresses;

            addresses = geocoder.getFromLocation(startPt.getLatitude(), startPt.getLongitude(), 1);
            String startPtStr = addresses.get(0).getAddressLine(0);

            addresses = geocoder.getFromLocation(endPt.getLatitude(), endPt.getLongitude(), 1);
            String endPtStr = addresses.get(0).getAddressLine(0);

            itemsList.add(new RouteItem(startPtStr, endPtStr, 3.4));
        }
        catch(FileNotFoundException e)
        {
            e.printStackTrace();
        }
        catch (IOException e) {
            e.printStackTrace();
        }
    }

    return itemsList;
}

public void onPostExecute(ArrayList<RouteItem> itemsList)
{
    super.onPostExecute(itemsList);

    adapter.setItemList(itemsList);
    adapter.notifyDataSetChanged();
}

 public GeoPoint getGeoPointFromString(String coordinates)
{
    String loadedLatStr = coordinates.substring(coordinates.indexOf("(") + 1, coordinates.indexOf(","));
    String loadedLongStr = coordinates.substring(coordinates.indexOf(",") + 1, coordinates.lastIndexOf(","));

    double loadedLat = Double.parseDouble(loadedLatStr);
    double loadedLong = Double.parseDouble(loadedLongStr);

    return new GeoPoint(loadedLat, loadedLong);
}

public String tail( File file ) {
    RandomAccessFile fileHandler = null;
    try {
        fileHandler = new RandomAccessFile( file, "r" );
        long fileLength = fileHandler.length() - 1;
        StringBuilder sb = new StringBuilder();

        for(long filePointer = fileLength; filePointer != -1; filePointer--){
            fileHandler.seek( filePointer );
            int readByte = fileHandler.readByte();

            if( readByte == 0xA ) {
                if( filePointer == fileLength ) {
                    continue;
                }
                break;

            } else if( readByte == 0xD ) {
                if( filePointer == fileLength - 1 ) {
                    continue;
                }
                break;
            }

            sb.append( ( char ) readByte );
        }

        return sb.reverse().toString();
    } catch( java.io.FileNotFoundException e ) {
        e.printStackTrace();
        return null;
    } catch( java.io.IOException e ) {
        e.printStackTrace();
        return null;
    } finally {
        if (fileHandler != null )
            try {
                fileHandler.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
    }
}
}

RouteList.java

public class RouteList extends AppCompatActivity {
ArrayList<RouteItem> itemsList;
ArrayList<String> routeFiles;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_route_list);

    itemsList = new ArrayList<RouteItem>();

    RouteListAdapter adapter = new RouteListAdapter(this, R.layout.route_list_item);
    ListView listView = (ListView) findViewById(R.id.routeList);
    listView.setAdapter(adapter);

    getRouteFiles();
    RouteLocationsTask task = new RouteLocationsTask(adapter, routeFiles, getApplicationContext());
    task.execute();
}

public void getRouteFiles()
{
    String path = Environment.getExternalStorageDirectory()+"/LocationTracker/Routes/";

    // Read all files sorted into the values-array
    routeFiles = new ArrayList();
    File dir = new File(path);

    String[] list = dir.list();
    if (list != null) {
        for (String file : list) {
            if (!file.startsWith(".")) {
                routeFiles.add(file);
            }
        }
    }
    Collections.sort(routeFiles);
}
}

Upvotes: 0

Views: 68

Answers (1)

shreyashirday
shreyashirday

Reputation: 900

Pass in your listview as a paramater to your RouteLocationsTask class and set the adapter in onPostExecute.

Like this:

RouteLocationsTask.java

public class RouteLocationsTask extends AsyncTask<Void, Void, ArrayList<RouteItem>>{

private RouteListAdapter adapter;
private ArrayList<RouteItem> itemsList;
private ArrayList<String> routeFiles;
private ListView listview;
private Context context;

public RouteLocationsTask(ListView listview, RouteListAdapter adapter, ArrayList<String> routeFiles, Context context)
{
    this.adapter = adapter;
    itemsList = new ArrayList<RouteItem>();
    this.routeFiles = routeFiles;
    this.context = context;
    this.listview = listview;
}

@Override
protected ArrayList<RouteItem> doInBackground(Void... params) {
    for (int i = 0; i < routeFiles.size(); i++) {

        File loadFile = new File(Environment.getExternalStorageDirectory()+"/LocationTracker/Routes/"+routeFiles.get(i));
        try {
            BufferedReader br = new BufferedReader(new FileReader(loadFile));

            //while ((line = br.readLine()) != null) {
            String firstEntry = br.readLine();
            GeoPoint startPt = getGeoPointFromString(firstEntry);

            String lastEntry = tail(loadFile);
            GeoPoint endPt = getGeoPointFromString(lastEntry);

            Geocoder geocoder = new Geocoder(context, Locale.getDefault());
            List<Address> addresses;

            addresses = geocoder.getFromLocation(startPt.getLatitude(), startPt.getLongitude(), 1);
            String startPtStr = addresses.get(0).getAddressLine(0);

            addresses = geocoder.getFromLocation(endPt.getLatitude(), endPt.getLongitude(), 1);
            String endPtStr = addresses.get(0).getAddressLine(0);

            itemsList.add(new RouteItem(startPtStr, endPtStr, 3.4));
        }
        catch(FileNotFoundException e)
        {
            e.printStackTrace();
        }
        catch (IOException e) {
            e.printStackTrace();
        }
    }

    return itemsList;
}

public void onPostExecute(ArrayList<RouteItem> itemsList)
{
    super.onPostExecute(itemsList);

    adapter.setItemList(itemsList);
    adapter.notifyDataSetChanged();
    listview.setAdapter(adapter);

}

 public GeoPoint getGeoPointFromString(String coordinates)
{
    String loadedLatStr = coordinates.substring(coordinates.indexOf("(") + 1, coordinates.indexOf(","));
    String loadedLongStr = coordinates.substring(coordinates.indexOf(",") + 1, coordinates.lastIndexOf(","));

    double loadedLat = Double.parseDouble(loadedLatStr);
    double loadedLong = Double.parseDouble(loadedLongStr);

    return new GeoPoint(loadedLat, loadedLong);
}

public String tail( File file ) {
    RandomAccessFile fileHandler = null;
    try {
        fileHandler = new RandomAccessFile( file, "r" );
        long fileLength = fileHandler.length() - 1;
        StringBuilder sb = new StringBuilder();

        for(long filePointer = fileLength; filePointer != -1; filePointer--){
            fileHandler.seek( filePointer );
            int readByte = fileHandler.readByte();

            if( readByte == 0xA ) {
                if( filePointer == fileLength ) {
                    continue;
                }
                break;

            } else if( readByte == 0xD ) {
                if( filePointer == fileLength - 1 ) {
                    continue;
                }
                break;
            }

            sb.append( ( char ) readByte );
        }

        return sb.reverse().toString();
    } catch( java.io.FileNotFoundException e ) {
        e.printStackTrace();
        return null;
    } catch( java.io.IOException e ) {
        e.printStackTrace();
        return null;
    } finally {
        if (fileHandler != null )
            try {
                fileHandler.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
    }
}
}

RouteList.java

public class RouteList extends AppCompatActivity {
ArrayList<RouteItem> itemsList;
ArrayList<String> routeFiles;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_route_list);

    itemsList = new ArrayList<RouteItem>();

    RouteListAdapter adapter = new RouteListAdapter(this, R.layout.route_list_item);
    ListView listView = (ListView) findViewById(R.id.routeList);


    getRouteFiles();
    RouteLocationsTask task = new RouteLocationsTask(listView,adapter, routeFiles, getApplicationContext());
    task.execute();
}

public void getRouteFiles()
{
    String path = Environment.getExternalStorageDirectory()+"/LocationTracker/Routes/";

    // Read all files sorted into the values-array
    routeFiles = new ArrayList();
    File dir = new File(path);

    String[] list = dir.list();
    if (list != null) {
        for (String file : list) {
            if (!file.startsWith(".")) {
                routeFiles.add(file);
            }
        }
    }
    Collections.sort(routeFiles);
}
}

Upvotes: 1

Related Questions