0

How do I go about making an HTTP request in a Clojure Android project?

  • neither clj-http nor http-kit seem to be Android-friendly
  • the approach in this question gives a android.os.NetworkOnMainThreadException

Attempting to resolve that Exception according to the answers given here has various problems. The preferred solution (using AsyncTask) requires subclassing, and I'm not entirely clear how to write Clojure code that does so. Trying to change StrictMode settings results in namespace-related errors. Finally, starting up a new thread to handle the web request with (.start (Thread. (fn [] ...))) crashes out the app entirely in testing.

So, once more: how do I go about making an HTTP request in an Android application written using Clojure Android?

Community
  • 1
  • 1
Inaimathi
  • 13,853
  • 9
  • 49
  • 93
  • 1
    you could try to use [retrofit](http://square.github.io/retrofit/) which is said work nice on android. Here's a simple example: https://github.com/bamboo/clojure-retrofit-spike – leetwinski Nov 30 '16 at 08:54
  • @leetwinski - no dice, looks like :/ Merely `import`ing `[retrofit.http GET Path]` causes the project to crash on-device. – Inaimathi Nov 30 '16 at 13:21

1 Answers1

1

Following the question you linked to above, their (maslurp) works in the android Clojure REPL app, if (.setDoOutput) is set to false instead, per this question, AND you wrap the call in a future (to avoid the android.os.NetworkOnMainThreadException) :

(defn maslurp [url]
  (let [a (new java.io.BufferedReader
               (new java.io.InputStreamReader
                    (.getInputStream (doto (.openConnection (new java.net.URL url))
                                       (.setRequestMethod "GET")
                                       (.setDoOutput false) ; false for GET
                                       (.setUseCaches false)))))]
    (loop [r (.readLine a) s ""]
      (if (nil? r)
        s
        (recur (.readLine a) (clojure.string/join [s r]))))))


@(future (maslurp "https://www.google.com"))
Community
  • 1
  • 1
  • This does not seem to solve the problem. The question is about running HTTP requests in an app built with [Clojure Android](http://clojure-android.info/) (added link to question to clarify). In that context, calling the above definition still raises an `android.os.NetworkOnMainThreadException`. – Inaimathi Dec 04 '16 at 05:21
  • There is the clojure-android neko library, which includes support for calling `(future (let [..] (on-ui (..)))`: [https://github.com/clojure-android/neko/search?utf8=%E2%9C%93&q=on-ui] – merryreaper Dec 04 '16 at 11:11