"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

Jon Tara
Ruby threads are not

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.

Vote: 
Vote up!
Vote down!

Points: 1

You voted ‘up’


Ameer Ilahi
hi Jon,as i was executing the

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

Vote: 
Vote up!
Vote down!

Points: 0

You voted ‘up’


Pietro Francesc...
It's better/safer/cleaner if

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

Vote: 
Vote up!
Vote down!

Points: 1

You voted ‘up’


Log in to post comments