アプリに ListView があり、getView() メソッドをオーバーライドして、行のテキストに応じて行の ImageView src を変更できるようにしました。
問題は、ListView のスクロールが遅れていることに気付きました。DDMS をチェックすると、ListView がスクロールされるたびにガベージ コレクターが呼び出されているようで、スクロールが遅くなります。
また、BufferedReader から行を読み取るときに、アプリの別の部分でガベージ コレクターが呼び出されていることに気付きました。これにより、2,000 行のファイルを開くのに約 47 秒かかります。携帯電話にインストールしたファイル エクスポーラーが開くと、約2秒で同じファイル。
私の質問は、ガベージ コレクションが 200 ミリ秒ごとに一定の原因で発生している可能性があることと、それを防ぐにはどうすればよいかということです。それは私のアプリを本当に遅くしています。私が解決しなければ、一部のユーザーを先延ばしにするのではないかと心配しています。
ありがとう、アレックス。
リストビュー 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;
}
アップデート:
ファイル読み取りの問題は解決されました。文字列の連結により、各ループの後にガベージ コレクターが呼び出され、ファイルの読み取りが劇的に遅くなることが判明しました。回答で示唆されているように、代わりに StringBuilder を使用しましたが、すぐに開きます-万歳!
2回目の更新:
ListView をスクロールするときに一定の GC が呼び出される原因はわかっていますが、これは ListView の属性 android:cacheColorHint="@android:color/transparent" ですが、回避策はわかりません。