класс MemoryFile любого использования?

Я планировал использовать общую память между активностью и службой в отдельном процессе для передачи большого контента между ними.

С этой целью я читаю всю информацию, которую я нашел в MemoryFile, и как ее передавать между действиями и, в частности, этой записью stackoverflow для чего нужен MemoryFile в android .

Но я не могу вызвать getParcelFileDescriptor (используя описанное решение) на моей версии Android 4.xx. Кажется, что этого метода больше не существует.

Тем не менее, я прихожу к следующему коду, чтобы отправить ParcelFileDescriptor в мою службу (примите это как псевдокод, но на самом деле это код ruboto):

shm = MemoryFile.new("picture", 1000)
f = shm.getFileDescriptor() 
p = ParcelFileDescriptor.dup( f)

b = Bundle.new()
b.putParcelable( "shm", p)
msg.setData( b)
service.send( msg)

Чтобы проверить правильность доступа к разделяемой памяти, я написал в ней строку и попытался получить ее на стороне службы.

У меня есть следующий (настоящий java) код для этого:

 Parcelable p = msg.getData().getParcelable("shm");
 ParcelFileDescriptor shm = (ParcelFileDescriptor) p;
 FileDescriptor f = shm.getFileDescriptor();

 if( f.valid()) {
     FileInputStream in = new FileInputStream( f);
     String s = readString( in); // this fail!
}

Все в порядке, f действителен, но я не могу прочитать из полученного fileDisscriptor, я получаю: java.io.IOException: read failed: EINVAL (неверный аргумент)

Код для чтения следующий:

public String readString(InputStream inputStream) throws IOException {
BufferedReader r = new BufferedReader(new InputStreamReader(inputStream));
String s = r.readLine();
return s;
}

Итак два вопроса:

  • Я делаю неправильно? (в любую сторону)
  • или MemoryFile, ампутированный из #getParcelFileDescriptor, теперь непригоден для использования в качестве средства для разделения памяти между двумя процессами?

В этом последнем случае я не вижу никакого интереса к этому классу...

Я видел другую статью, в которой упоминается код JNI для использования общей памяти, но хотел бы избежать этой дополнительной сложности.


person yves    schedule 04.11.2013    source источник


Ответы (1)


Мне удалось передать данные между приложениями через MemoryFile на Android 4.0.4, используя shm.getFileDescriptor() и ParcelFileDescriptor.dup(f), так что, к счастью, этот класс все еще можно использовать. В вашем случае проблема может быть в содержимом файла, хотя я не знаю, как это может вызвать ошибку Invalid arguments. Попробуйте записать и прочитать массив байтов фиксированной длины вместо строки (которую вы на самом деле не пишете в предоставленном коде) и просто прочитать его с помощью InputStream.read(buffer).

person lapis    schedule 22.12.2013
comment
Хотя у меня это работало только для первого чтения/записи, после этого удаленная сторона ничего не могла прочитать, а после прохода GC дескриптор файла стал недействительным. Похоже, вы должны использовать mmap и другие нативные функции, чтобы заставить его работать правильно, поэтому в итоге я использовал LocalSocket для своей задачи вместо MemoryFile. - person lapis; 24.12.2013