Чтобы IO не блокировал поток пользовательского интерфейса в моем приложении для Android, я пытаюсь переместить операцию записи файла в отдельный поток. Это код, я использую, чтобы начать с низким приоритетом нитяным писать 1Mb из буфера байт:Операция ввода-вывода в другой ветке, перекрывающей мою ветку пользовательского интерфейса?
Thread t = new Thread(new Runnable()
{
@Override
public void run()
{
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
try
{
FileOutputStream fos = new FileOutputStream(filename));
try
{
final java.nio.channels.FileChannel outChannel = fos.getChannel();
outChannel.write(byteBuffer);
fos.getFD().sync();
}
finally
{
if (fos != null)
fos.close();
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
});
t.setPriority(Thread.MIN_PRIORITY);
t.start();
Этих потоки запускаются в моем приложении, когда некоторые события пользовательского интерфейса произойдут. К сожалению, я по-прежнему замечаю огромную задержку. Мой пользовательский интерфейс будет замораживаться в течение ~ 2 секунд каждые 10 или около того раз, когда я запускаю/завершаю один из вышеперечисленных потоков. Если я прокомментирую код потока, эти задержки исчезнут.
Что я могу сделать, чтобы остановить эту операцию ввода-вывода от блокировки моего потока пользовательского интерфейса?
Я не уверен, что теперь делать, чтобы диагностировать проблему. Я понял, что поток IO блокируется, когда «outChannel.write» произошло, поскольку он ожидал завершения операции ввода-вывода, что означало бы, что мой поток пользовательского интерфейса немедленно возьмет верх. В этом случае для операции записи требуется большой кусок мощности процессора?
Edit:
С StrictView на (который я уверен, потому что он поймал несколько несвязанных проблем ввода-вывода в потоке пользовательского интерфейса, что я фиксированный первым), я могу подтвердить, нет IO происходит в моем IO потоке.
Результаты бегущей трассировки довольно загадочны. Проблема пользовательского интерфейса заключается в том, что когда я выполняю операции перетаскивания, каждые 10 или около того раз я делаю это, устройство, похоже, замерзает примерно на 0,5-1 с. Вещь, которую вы перетаскиваете, замерзнет, и после задержек в конечном итоге произойдет переход туда, где находится ваш палец. В отслеживании я продолжал перетаскивать, пока это не произошло. В случае, когда это происходит в traceview, мои фоновые потоки не запускаются, но есть внезапный блок около 1 секунды, где операции в моем потоке пользовательского интерфейса, которые обычно бывают быстрыми, требуют более продолжительной работы x10. Например, вызов .drawBitmap (с растровым изображением с фиксированным размером) показан как принимающий ~ 0.2s для выполнения, когда каждый раз до этого один и тот же вызов .drawBitamp занимает десятую часть этого времени. Я мог просто читать это неправильно, но я не знаю, куда идти отсюда или что искать.
Это не тот поток, на который говорят, что блокирует ваш пользовательский интерфейс. Это только ОС, записывающие данные на карту. Файл ввода/вывода может быть медленным. Ваш вызов 'fos.getFD(). Sync();' скорее всего вызывает заикание. – Falmarri
Итак, вы говорите, что любая операция записи, которую я выполняю, блокирует пользовательский интерфейс? Какой смысл переместить его в другой поток? Он все еще заикается, когда я вынимаю .sync, но реже. В любом случае, это не идеально, потому что тогда у меня нет гарантии, что мой файл был записан на диск. – rbcc