Skip to content

Instantly share code, notes, and snippets.

@tito
Last active January 24, 2016 16:55
Show Gist options
  • Save tito/09c42fb4767721dc323d to your computer and use it in GitHub Desktop.
Save tito/09c42fb4767721dc323d to your computer and use it in GitHub Desktop.
Detect Thread exit to run jnius.detach() on Android
# Goal: detect when a thread exit to call jnius.detach()
# and prevent crash from Android/ART
# So we listen to "return" events from the "run" function of the threading.Thread
# The profiling function given to threading.set_profilefunc() is installed in the
# thread before the run() function of the Thread.
# All we need to do is filter on "return" event of the "run" function for the
# original Thread.run() of Python's threading.py
# ERROR: it doesn't detect when a thread crash (python exception)
import threading
try:
import jnius
except:
jnius = None
def thread_check_exit(frame, event, arg):
if event != "return":
return thread_check_exit
code = frame.f_code
if code.co_name != "run":
return thread_check_exit
if not code.co_filename.endswith("/threading.py"):
return thread_check_exit
try:
if jnius:
jnius.detach()
except:
pass
return thread_check_exit
threading.setprofile(thread_check_exit)
# EDIT: this doesn't for threads, sorry. :(
try:
import jnius
import sys
excepthook_orig = sys.excepthook
def jnius_excepthook(*args):
jnius.detach()
return excepthook_orig(*args)
sys.excepthook = jnius_excepthook
except ImportError:
pass
# alternative approach that works when the thread got an exception as well
import threading
try:
import jnius
except:
jnius = None
if jnius:
orig_thread_run = threading.Thread.run
def thread_check_run(*args, **kwargs):
try:
return orig_thread_run(*args, **kwargs)
finally:
jnius.detach()
threading.Thread.run = thread_check_run
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment