Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Buildozer compiles apk, but it crashes on android

I am able to build an .apk, but after I install it on my android phone it simply crashes at startup. My thoughts for failing is that I am using 3rd party libraries e.g(beautifulsoup).

This is how my imports look in 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

I'm running mavericks 10.9.3

Does it have something to do with buildozer.spec file? I've tried adding BeautifulSoup to app requirements, but it doesn't change a thing.

Any help would be appreciated.

like image 823
Emke Avatar asked May 30 '14 10:05

Emke


1 Answers

I ran into this problem as well, but I was (apparently) able to get everything working fine with a workaround. Since it doesn't look like you posted a logcat, I'll assume you ran into the same issue I did.

Yes, you do need to list beautifulsoup4 as a requirement in your spec. From looking into bs4's code, it looks like bs4 is willing to use any of several "builders." It supports HTMLParser, html5lib, or lxml. I have no idea why we can't load HTMLParser, but it's actually the least preferred library of the three, and if it weren't for the fact that there's no try block around the import, it seems that everything would work fine (as long as one of the other parsing libraries was available).

With this in mind, I included one of the other libraries, and I decided to hack the import process so that Python would pretend _htmlparser loaded okay :)

This article was instructive: http://xion.org.pl/2012/05/06/hacking-python-imports/

The end result was something like this:

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

I also added html5lib to the requirements in buildozer.spec.

Now, is this the right way to solve the problem? I don't know. The best approach would probably be to request that the author fix it. It might be as simple as to put the import in a try block. Nevertheless, this is the approach I've gone with for the moment, and it is at least an interesting exercise, and a way to test your app until a better fix comes along.

Additionally, I should warn you that I only did this recently, so I can't 100% guarantee that it won't cause any problems, but at a minimum, it's worked well enough to get my app running and scraping the particular website I was interested in. Good luck!

like image 147
Will Avatar answered Oct 19 '22 10:10

Will