3 Replies Latest reply on Sep 25, 2013 6:31 AM by Ameer Ilahi

    "JNIEnv is not set for this thread" when using Threads

      hi,

      I have an application where i need to download large files from a web-service (using the net/http library). Based on the file requested by the users, i have a thread which fires off in the background to download the file while the users continues work in other sections of the application; once the download is complete the user get an alert that the download is complete.

      I have accomplished this using a Thread (in a separate class which is not a controller):

      @download_thread = Thread.new { 
          self.init_download(); 
      }
      

       

      All worked good until I ran the application on an Android device where I am getting the following error:

      JNIEnv is not set for this thread.
      

       

      I have found a number of posts (https://developer.motorolasolutions.com/message/4637 , https://developer.motorolasolutions.com/message/6278, https://groups.google.com/forum/#!topic/rhomobile/vOM6_k3SfaE) suggesting that Threads are not supported on Android and as an alternative Rho::Timer should be used. The first of these posts suggests that the issue will be fixed in RhoElements 2.2, however as I am using the same version, the issue remains unresolved.

       

      I have given the Rho::Timer a go, however when I call the download function in the Timer callback the application hangs until the download operation is completed, which is not what I want to happen. Any suggestions what else I could use here? Is the issue been addressed in RhoMobile 4?

       

      Thanks

        • Re: "JNIEnv is not set for this thread" when using Threads
          Jon Tara

          Ruby threads are not supported for Android in 2.x. I do't know about 4.x

           

          RhoTimer is not a solution if you are doing HTTP. You will need to use AsyncHttp with a callback. Apparently you are using AsyncHttp synchronously (e.g. without a callback) and that will tie-up everything while it waits for data.

          1 of 1 people found this helpful
            • Re: "JNIEnv is not set for this thread" when using Threads

              hi Jon,

              as i was executing the HTTP request in a thread, so the request was being made synchronously. i have now replaced Net::HTTP::Post with AsyncHttp.

              i still had to make use of RhoTimer to ensure that the download queue is processed for the documents queued by the user; and to check periodically if any new download item which might have been missed is available for downloading.

               

              thanks

            • Re: "JNIEnv is not set for this thread" when using Threads
              Pietro Francesco Maggi

              It's better/safer/cleaner if you unwind your call in an asynchronous way.

              Using AsyncHTTP in Rhodes 3.5 or Network API in Rhodes 4.0 and handling the result in a callback.

               

              cleaner, safer and better.

               

              with v4.0 you can have something like this in you controller:

                def get_request
                  #Perform an HTTP GET request.
                  getProps = Hash.new
                  getProps['url'] = "http://<URL>:<Port>?<Paramerters>"
                  getProps['headers'] = {"Content-Type" => "application/json"}
                  Rho::Network.get(getProps, url_for(:action => :get_callback))
                  render :action => :transferring
                end
              
                def get_callback
                  if @params['status'] == "ok"
                    get_result =
                    get_result = Rho::JSON.parse(@params['body'])
                    # use get_result in some smart way
                end
              end
              

               

              I think that in Rhodes and in WEB apps in general Async is usually better than Sync.

               

              ~Pietro

              1 of 1 people found this helpful