Shikhar13 / codenameone

Automatically exported from code.google.com/p/codenameone
0 stars 0 forks source link

AndroidImplementation creates a WebView to get default User-Agent #294

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
Display.init(Object) setsthe default User-Agent, which causes a WebView to 
always be created on start-up. I do not believe that this is the desired 
behavior as it causes the app to use a lot of memory at start up and causes 
several threads to be created that persist for the life of the app (this has 
come up in the discussion thread titled "Android WebView"). This is over-kill 
especially for apps that do not need the User-Agent.

I propose that the User-Agent be generated in a similar way that it is 
generated in the WebSettings class (see 
http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/and
roid/4.0.4_r1.2/android/webkit/WebSettings.java#WebSettings.getCurrentUserAgent(
))

I took the code from the WebSettings class and modified it to work outside of 
the class. I have attached a java file that shows the code used as a Native 
interface that I tested on a android device. It contains two methods that could 
be inlucded in the Android Implementation to remove the need for creating a 
WebView.

Original issue reported on code.google.com by Ian.Te...@gmail.com on 13 Aug 2012 at 9:52

Attachments:

GoogleCodeExporter commented 9 years ago
Assigning to Chen for evaluation

Original comment by shai.almog on 14 Aug 2012 at 3:42

GoogleCodeExporter commented 9 years ago
I'm afraid this approach will not work, OEM are free to change the user agent 
on the device, see this blog post:
http://android-developers.blogspot.co.il/2010/12/android-browser-user-agent-issu
es.html

"We recommend that manufactures of large-form-factor devices (where the user 
may prefer the standard web site over a mobile optimized version) remove 
"Mobile" from the User Agent (and keep the rest of the User Agent as currently 
implemented). Web sites can then key off "Mobile" in the User Agent to decide 
on which UI version to present to the device. "

Original comment by cf27...@gmail.com on 15 Aug 2012 at 12:45

GoogleCodeExporter commented 9 years ago
I do not see how this affects this method of getting the User Agent. The code I 
supplied will generate the same string that would have been created if a 
WebView was created. The code comes directly from the WebSettings class with 
some small changes so that it works outside of the class. If the OEM changes 
the User Agent, it should be reflected in the code I supplied. The only 
downside that I see is that the way the User Agent is created may change in 
future, but seeing how the code has barely changed since android 1.5, I don't 
think that should pose a big problem.

I'm sorry if I'm missing something, but I don't understand how the code I 
supplied doesn't comply with the blog post.

Original comment by Ian.Te...@gmail.com on 15 Aug 2012 at 1:05

GoogleCodeExporter commented 9 years ago
since android is an open platform every OEM can change the code, the code you 
supplied is the default android implementation but OEM are changing this code.

Original comment by cf27...@gmail.com on 15 Aug 2012 at 1:33

GoogleCodeExporter commented 9 years ago
Ok, I didn't consider the OEMs changing the WebSettings class code, I just 
assumed that the User Agent would be changed by OEMs using the 
com.android.internal.R.string.web_user_agent (and possibly the 
web_user_agent_target_content) property, in which case the code I supplied 
would work.

Thanks for at least looking into this.

Original comment by Ian.Te...@gmail.com on 15 Aug 2012 at 2:19

GoogleCodeExporter commented 9 years ago
Another way to address this issue that you may want to consider is to get the 
default User Agent when the first ConnectionRequest is made. Remove the 
ConnectionRequest.setDefaultUserAgent call from Display.init. Then define 
ConnectionRequest.getDefaultUserAgent to

public static String getDefaultUserAgent() {
    if(defaultUserAgent == null) {
        Display.getInstance().getProperty("User-Agent", 
                "Mozilla/5.0 (SymbianOS/9.4; Series60/5.0 NokiaN97-1/20.0.019; Profile/MIDP-2.1 Configuration/CLDC-1.1) AppleWebKit/525 (KHTML, like Gecko) BrowserNG/7.1.18124");
    }
    return defaultUserAgent;
}

This has the benefit of not creating a WebView for apps that don't need to make 
ConnectionRequest's. In addition, the default User Agent can be set manually 
before the first ConnectionRequest is made to avoid the WebView from being 
created if a different User Agent is desired to spoof the UserAgent.

Original comment by Ian.Te...@gmail.com on 15 Aug 2012 at 6:27

GoogleCodeExporter commented 9 years ago
that's make sense, I'll have a look, thanks

Original comment by cf27...@gmail.com on 16 Aug 2012 at 2:01

GoogleCodeExporter commented 9 years ago
Also, if the WebView has to be created to get the UserAgent, it should probably 
be destroyed. "m_webview.destroy();" should probably be inserted at lines 1364 
and 1372 of AndroidImplementation.java after the UserAgent is determined.

Original comment by Ian.Te...@gmail.com on 19 Aug 2012 at 3:48

GoogleCodeExporter commented 9 years ago
looking at the code again.

we are not creating a webview to get the user-agent.

        try {
            Constructor<WebSettings> constructor = WebSettings.class.getDeclaredConstructor(Context.class, WebView.class);
            constructor.setAccessible(true);
            try {
                WebSettings settings = constructor.newInstance(activity, null);
                return settings.getUserAgentString();
            } finally {
                constructor.setAccessible(false);
            }
        } catch (Exception e) {

         //the webview creation will occur only here, if the above has failed.

        }

Original comment by cf27...@gmail.com on 27 Aug 2012 at 2:40

GoogleCodeExporter commented 9 years ago
Yes, I saw this before, but I remember seeing some of the WebView threads after 
I had  just started the app (before creating one myself); in addition, the same 
behavior was seen by someone else int he discussion post I mentioned before 
titled "Android WebView". This means that at least on some devices, creating a 
WebSettings object fails and a WebView is created.

However, in this case, I agree that it is probably not possible to prevent 
creating a WebView object in all cases/devices.

I don't know if you want to keep this issue alive to try and address it in the 
future, but you can close it if you want because I don't see a way of getting 
around creating a WebView anymore.

Thanks again for looking into this.

Original comment by Ian.Te...@gmail.com on 27 Aug 2012 at 6:26

GoogleCodeExporter commented 9 years ago

Original comment by cf27...@gmail.com on 30 Aug 2012 at 7:31