2014-02-03 2 views
0

Мое приложение отображает много изображений и кэширует их в памяти, поэтому использует память большого объема (около 40 МБ кучи). С другой стороны, он загружает большой файл 7zip (300 МБ) и извлекает их с помощью собственного кода, который использует много памяти и обработки. Иногда извлечение невозможно, но после перезагрузки приложения он работает. Хотя я не получаю никакого исключения, поскольку это собственный код, я считаю, что это из-за нехватки памяти.Сервис в другом процессе

Поэтому я решил поместить извлечение в другом процессе, чтобы я мог убить его после его завершения (здесь стоимость нового процесса не является вопросом, потому что сначала работа важнее, а извлечение - это тяжелый процессор, который сам по себе). Но теперь, прежде чем убить процесс, я должен проверить, не запущено ли другое извлечение. У меня возникло два решения:

1- Начать новый процесс для каждого извлечения. (Я не знаю, возможно ли это в андроиде)

2- Как-то проверить, не запущено ли другое извлечение и если не убьют процесс. (Это может привести к выходу из памяти)

3- Как-то дождитесь завершения извлечения, прежде чем начинать новый. (это очень сложно, как это должно быть сделано между различными процессами)

Как я не могу понять, как это сделать, мне действительно нужны советы экспертов.

--EDIT ------------------------------------------- ----

Я проверил извлечение 400-мегабайтного 7zip-файла. После первого извлечения он всегда терпит неудачу. Таким образом, процесс должен быть убит после каждого извлечения и нового запуска. Таким образом, второй вариант отсутствует в списке!

И для записи, родной код 7zip не мой, это Andro7Z, основанный на 7ZA linux, и даже если бы я сам скомпилировал его, но я действительно не хочу с ним связываться.

+0

Вы можете поместить сервис извлечения в отдельный процесс, но зачем вам его убивать, когда это будет сделано? Если вы запрограммировали это правильно, он должен иметь возможность восстановить всю используемую память. Если нет, вам нужно исправить это - не ищите способ работать с негерметичным кодом. Сколько пользователей хочет, чтобы на телефоне была какая-то неисправная память? –

+0

@DavidWasser Собственно код 7zip не мой. Это Andro7z, основанный на 7za linux. И я предпочитаю убивать его после этого, чтобы память была полностью исправлена. Я еще не проверял, но что, если второй экстракт не получит достаточного количества памяти. С другой стороны, это мой последний и самый надежный вариант, потому что в одно время не будет двух или более извлечений. – Ali

+0

Либо вы не вызываете правильные методы в библиотеке, чтобы освободить память, либо библиотека имеет утечки памяти. Вы должны поговорить с людьми, которые создали библиотеку. –

ответ

1

Ну, если вы действительно должны ... вы можете разместить свою добычу внутри Service, поместите Service в отдельный процесс.

Вы разрешаете только одно извлечение в одно время (вы можете сами это контролировать). Если вы используете startService(), чтобы начать извлечение, Android обеспечит, чтобы у вас только один экземпляр Service. В onStartCommand() вы должны проверить, есть ли у вас процесс извлечения, если вы можете отказаться от запроса или поставить его в очередь в базу данных или что угодно. Если нет, вы начинаете новую тему, чтобы выполнить извлечение.

Как только извлечение завершено, процесс может убить себя. Следующая попытка извлечь (используя startService()) приведет к созданию Android нового процесса и запуску нового экземпляра Service.

+0

Что делать, если это сделано в IntentService? Является ли IntentService ограниченным одним экземпляром или может быть больше? – Ali

+0

Другой вопрос: Есть ли способ проверить, работает ли служба, и как-нибудь подождать, пока она не будет закончена, прежде чем отправлять новое намерение? – Ali

+0

Все службы Android существуют только один раз. Android управляет этим для вас. –

0

Если я хорошо понял, вы пытались извлечь файл. Я буду рассматривать только код Android, код экстрактора может содержать утечки памяти.

Но вы можете использовать класс AsyncTask, чтобы поместить этот процесс в фоновом режиме и получить обратный вызов после его завершения. Также, если вам нужно отслеживать ваши задачи извлечения, вы также можете использовать список экземпляров своей задачи, таким образом вы можете контролировать их и точно знать, сколько еще выполняется или отменить их.

Итак, я хотел бы создать что-то вроде:

ExtractTaskController - отвечает за создание, управление и проведение ссылки на задачи. ExtractAsyncTask - расширение класса AsyncTask и выполнение фактического извлечения.

+0

Тип файла: 7Z, android не поддерживает их. Файлы большие, поэтому java 7Z не может их извлечь. Поэтому это должно быть сделано с использованием собственного кода. – Ali

+0

@ Как я уже сказал, вы можете поместить эти внутренние вызовы внутри AsyncTask, после того, как он закончится, вы можете удалить ваши использованные ресурсы. Если вы хотите сделать это за один раз, вы также можете реализовать стек в контроллере. – eslimaf

+0

У меня нет контроля над родной библиотекой, и поэтому я не могу освободить ресурсы. Поэтому я решил применить другой процесс. – Ali

Смежные вопросы