У меня есть ListView в моем приложении, и я переопределил метод getView (), чтобы я мог изменить src ImageView строки в зависимости от текста строки.
Проблема в том, что я заметил, что прокрутка ListView запаздывает, и когда я проверяю DDMS, кажется, что сборщик мусора вызывается при каждой прокрутке ListView, тем самым замедляя прокрутку.
Я также заметил, что сборщик мусора вызывается в другой части моего приложения при чтении строк из BufferedReader, что делает открытие файла из 2000 строк занимает ~ 47 секунд, тогда как в качестве средства проверки файлов я установил на него телефон открывает тот же файл примерно за 2 секунды.
Итак, мой вопрос: что может вызывать постоянную сборку мусора каждые 200 мс или около того, и как мне предотвратить это? Это действительно замедляет работу моего приложения, и я боюсь, что это оттолкнет некоторых пользователей, если я не решу его.
Спасибо,
Алекс.
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);
}
}
Код для открытия файла
На днях я удалил код, который регистрировал, сколько секунд потребовалось, чтобы открыть файл, но это заняло 47 секунд и определенно заняло слишком много времени, и снова, пока цикл while работает, есть постоянные вызовы сборщику мусора, который я догадываюсь из-за медленного чтения файла - и да, эта функция вызывается в потоке с показом progressDialog во время чтения файла
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:
Проблема с чтением файла решена, получается, что конкатенация String заставляет сборщик мусора вызываться после каждого цикла, что значительно замедляет чтение файла. Как подсказывает ответ, я вместо этого использовал StringBuilder, и теперь он открывается через секунду - ура!
2-е ОБНОВЛЕНИЕ:
Я знаю причину постоянных вызовов GC при прокрутке моего ListView, это атрибут ListView android: cacheColorHint = "@ android: color / transparent" - но я не знаю обходного пути!