Buildozer компилирует apk, но он падает на android

Я могу построить .apk, но после того, как я установил его на свой телефон android, он просто падает при запуске. Мои мысли о неудаче в том, что я использую сторонние библиотеки e.g (beautifulsoup).

Так выглядит мой импорт main.py:

from kivy.app import App
from kivy.properties import ListProperty, StringProperty
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.uix.scrollview import ScrollView
from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition

import time, os, random, urllib2, re, cookielib as cj

from bs4 import BeautifulSoup as bs
from functools import partial

Я запускаю mavericks 10.9.3

имеет ли это какое-то отношение к buildozer.Spec-файл? Я попытался добавить BeautifulSoup в требования приложения, но это ничего не меняет.

любая помощь будет будьте благодарны.

2 ответов


я столкнулся с этой проблемой, но я (по-видимому) смог заставить все работать нормально с обходным путем. Поскольку не похоже, что вы опубликовали logcat, я предполагаю, что вы столкнулись с той же проблемой, что и я.

да, вам нужно перечислить beautifulsoup4 как требование в вашей спецификации. Из просмотра кода bs4 похоже, что bs4 готов использовать любой из нескольких "строителей"."Он поддерживает HTMLParser, html5lib или lxml. Я понятия не имею, почему мы не можем загрузить HTMLParser, но это на самом деле меньше предпочтительная библиотека из трех, и если бы не тот факт, что нет блока try вокруг импорта, кажется, что все будет работать нормально (пока одна из других библиотек синтаксического анализа была доступна).

имея это в виду, я включил одну из других библиотек, и я решил взломать процесс импорта, чтобы Python притворялся, что _htmlparser загружен хорошо:)

эта статья была поучительной: http://xion.org.pl/2012/05/06/hacking-python-imports/

конечный результат был примерно таким:

import imp
import sys

class ImportBlocker(object):

    def __init__(self, *args):
        self.black_list = args

    def find_module(self, name, path=None):
        if name in self.black_list:
            return self

        return None

    def load_module(self, name):
        module = imp.new_module(name)
        module.__all__ = [] # Necessary because of how bs4 inspects the module

        return module

sys.meta_path = [ImportBlocker('bs4.builder._htmlparser')]
from bs4 import BeautifulSoup

Я также добавил html5lib к требованиям в buildozer.спекуляция.

теперь, это правильный способ решить проблему? Я не знаю. Лучшим подходом, вероятно, было бы попросить автора исправить это. Это может быть так же просто, как поместить импорт в блок try. Тем не менее, это подход, с которым я пошел на данный момент, и это, по крайней мере, интересное упражнение и способ проверить ваше приложение, пока не появится лучшее исправление.

кроме того, я должен предупредить вас, что я сделал это только недавно, поэтому я не могу 100% гарантировать, что это не вызовет никаких проблем, но, как минимум, это сработало достаточно хорошо, чтобы мое приложение работало и очищало конкретный веб-сайт, который меня интересовал. Удачи!


Я понимаю, что этому вопросу несколько лет. Я думаю, что ответ @Will был фантастическим, но, к сожалению, в моем случае я не мог его использовать, потому что html5lib был слишком медленным для того, что я делал. Так что это для справки; для тех, кто абсолютно должен использовать встроенный парсер. Это не очень красиво, но вполне управляемо.

вопрос

после долгого расследования, я прибил причину проблемы. В журнале buildozer я заметил, что есть проблема компиляции файла _htmlparser с чтением журнала следующим образом (мой путь к проекту заменен на ):

Compiling <project-path>/.buildozer/android/platform/build/dists/mypackage/private/lib/python2.7/site-packages/bs4/builder/_htmlparser.py ...
SyntaxError: ("(unicode error) \N escapes not supported (can't load unicodedata module)", ('<project-path>/.buildozer/android/platform/build/dists/mypackage/private/lib/python2.7/site-packages/bs4/builder/_htmlparser.py', 135, None, 'data = u"\N{REPLACEMENT CHARACTER}"\n'))

поскольку он не компилировался, он не был включен в встроенный файл apk. Поэтому я посмотрел на файл и на строку, которая вызывала проблему:data = u"\N{REPLACEMENT CHARACTER}", который должен быть заменен data = u"\ufffd"

быстро исправить

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

чуть лучше исправить

было бы неплохо, если бы исправление было упаковано в наш код, поэтому, черпая вдохновение из ответа @Will, вот код, который вам нужно будет ввести перед импортом bs4:

import sys

class ImportFixer(object):
    def __init__(self, mname):
        self.mname = mname

    def find_module(self, name, path=None):
        if name == self.mname:
            return self
        return None

    def load_module(self, name):
        import _htmlparser as module
        module.__name__ = name
        return module

sys.meta_path = [ImportFixer('bs4.builder._htmlparser')]
from bs4 import BeautifulSoup

главное отличие в том, что вам нужно чтобы скопировать _htmlparser.py файл из пакета bs4 в ваш текущий каталог и исправить вышеупомянутую строку data = u"\N{REPLACEMENT CHARACTER}" С data = u"\ufffd"

затем, каждый раз, когда модуль bs4 импортируется, импорт волшебным образом перехватывается и используется локальный файл.

предупреждение: если вы когда-нибудь обновите красивый суп, вам может потребоваться использовать более свежий _htmlparser.py файл в вашем проекте с тем же исправлением, что и при необходимости.

последний комментарий

если я сделал некоторые опечатки, грамматические ошибки или вообще не имели смысла, имейте в виду, что я работал большую часть выходных, чтобы исправить это, и, честно говоря, я не думаю прямо. Прокомментируйте, если у вас есть какие-либо вопросы, и я отвечу и/или отредактирую свой ответ, когда у меня будет шанс.