If I call WebView.destroy() and I have a reference to that view somewhere else in my code, is there a way to detect that the webView has been destroyed? I was looking for something like WebView.isDestroyed().
As a hack right now I have added the following in my code. I have no idea how reliable or useful checking the context will be. Does destroy set the context to null, I quickly glanced at the source code for WebView.java in android, but it was a little over my head, almost all calls just got forwarded to mProvider, I didn't want to dig much longer if StackOverflow has my answer.
public void isWebViewDestroyed(WebView v)
{
return v.getContext() == null;
}
if(webView==null)
should be sufficient.
Related
Would like to ask for some advice on what's best way to implement on enabling and disabling the web view on Android?
I have this app wherein it can open urls within (by using web views) which then popups up and covers 80% of the UI, when the user navigates to another page of the app it should hide/close the web view but can be re-opened again when needed.
Here's a snippet of the code
private WebViewInterface webViewInterface = new WebViewInterface() {
#Override
public void onOpenURL(String url) {
navBrowserWV.setVisibility(View.VISIBLE);
navBrowserWV.getSettings().setJavaScriptEnabled(true);
navBrowserWV.setWebViewClient(new WebViewClient() {
#Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error){
handler.proceed();
}
});
navBrowserWV.loadUrl(url);
}
};
then this is how I close it
private void closeWebView() {
Log.d(LOGTAG, "closing webview...");
// Destroy WebView if it exists
if (this.navBrowserWV != null) {
this.navBrowserWV.stopLoading();
this.navBrowserWV.loadUrl("about:blank");
this.navBrowserWV.clearHistory();
this.navBrowserWV.clearCache(true);
this.navBrowserWV.pauseTimers();
this.navBrowserWV.setVisibility(View.GONE);
}
}
The problem with this implementation is that it displays the page properly at first but when I close it and then open the web view again with a url, it does not load the page anymore just a white background (no errors on the logger btw).
Would like to ask for help on how to resolve this one. Thanks
Finally, after a long time of digging up answers on the internet I found this old post regarding killing Android webview [link].
There's no real way to kill the WebView (it will always run in your process and you can't do anything about it ATM). So you only have to tell the WebView to load a bogus page, for me I did:
this.navBrowserWV.loadUrl("about:blank");
And it works now!
Quote from the website
4.1 .getSettings().setJavaScriptEnabled() Inhalt
Well, you would think that disabling JavaScript in the WebView’s settings would have an instant effect, in short: it does not. Only after reloading the page would there be no javascript any more, and this is not nice by design, since the page is still more or less well rendered.
4.2 .stopLoading() Inhalt
Since XHR „loads“ something from another server, you might think that calling „webview.stopLoading()“ would have an effect. In short: it does not. Works only on ressources contained within the HTML-file. Pity, is it not… Well, maybe not, since there is no „startLoading()“ method to resume XHR after resuming the activity anyway.
4.3 .destroy() Inhalt
As a last resort one might think about „destroy()“ing that thing, and true enough, the WebView itself is not accessible after that. Its threads however continue to exist as zombies somewhere in the vast RAM space and also continue to send XHR requests…
4.4 .pauseTimers() / resumeTimers() Inhalt
In short: Nope, does not work. I even don’t know what these methods are good for if not for controlling JavaScript timers. There aren’t any in plain HTML, AFAIK.
Update: When it comes to timers only, these functions seem to work on 2.3.5 and upwards, however, when there is no timer active at the time of calling the function, all in vain. With my use case: When pausing the app while there is an XHR active (instead of the running timer that schedules the next XHR call), nothing happens and the next timer continues unhindered.
I hope this will help someone who has the same problem as mine.
I've been looking around a lot lately but haven't really found much on this.
I'm making my third Android app and I'm looking to implement an intro screen on first run of the app where a series of images are shown explaining the apps functionality and the idea behind it; you can swipe the images left or right and at the last image you get to the app by swiping.
I really like the sort of thing they have done with the CamScanner app but despite my searching I have no idea how to implement it other knowing a little bit about some people referring to Fragments. Any help would be appreciated greatly and since we need better UI on Android, a good answer would help a lot of developers take the cue! :)
create a method to show popup window. show images in a scroll view in that popup. at last image set touch listener to dismiss that popup.
and call that method from onResume method of your Activity like this
protected void onResume(){
super.onResume();
SharedPreferences pref = getSharedPreferences(MyPrefs, MODE_PRIVATE);
boolean b = pref.getBoolean("FirstTime",true);
if(b)
{ new Handler().postDelayed(new Runnable() {
public void run() {
showIntroPopup();
}
}, 100);
}
}
in that popup set "FirstTime" boolean to false in SharedPreferences.
I saw online this code used a lot:
public void onAccelerometerChanged(final AccelerometerData myAccelerometerData) {)
When I try to use it, eclipse will not recognize the AccelerometerData class.
I'm having a hard time:
Detecting tilt.
Using it to change the worlds physics with box2d.
It would help me if anyone could show me ways of detecting tilting and using it.
Thank you.
You can see this code used in the PhysicsExample where it is used to change the center of gravity.
You must use the same code branch as the one in the example you have found. Notice that I linked GLES2-AnchorCenter branch version of the PhysicsExample. This branch is the newest. There is no AccelerometerData class. It has been renamed to AccelerationData.
Tilting (phone orientation) can be detected in a similar fashion. You have to call the following methods in your Activity and pass the correct listener.
protected boolean enableOrientationSensor(final IOrientationListener pOrientationListener) {
return this.mEngine.enableOrientationSensor(this, pOrientationListener);
}
protected boolean enableOrientationSensor(final IOrientationListener pOrientationListener, final OrientationSensorOptions pLocationSensorOptions) {
return this.mEngine.enableOrientationSensor(this, pOrientationListener, pLocationSensorOptions);
}
This is really an odd problem. The basic gist of it is what the title says. I have an adapter, which I am updating and calling notifyDatasetChanged() The problem however, is it does not work, unless the device has been rotated at least once. I can't for the life of me figure out why, what is being done differently after a rotation occurs?
The code in question is here:
The ASyncTask that handles it..
protected void onPostExecute(ArrayList<Records> result) {
if (ca == null)
{
ca = new CoverAdapter<Records>(c, R.layout.grid_cover_with_text_item, result);
}
if (gv.getAdapter() == null)
{
gv.setAdapter(ca);
}
else
{
new AdapterHelper().update((CoverAdapter) ca, result);
ca.notifyDataSetChanged;
}
}
With "ca" being my adapter, "gv" being my GridView and AdapterHelper().update being a method I found here to clear the adapter and add all the results of the arraylist to it, so it should be being updated properly.
Remember, this code works after the device has been rotated. Very confused right now, any insight would be appreciated. Thanks in advance.
Use the debugger and step through the code to check what is expected actually happens.
Glad you found the problem... Now you can ditch the AdapterHelperclass which is a waste.
I have the following code which gets call in my main activity's onCreate method
public static ErrorReporter getInstance(){
if (instance == null){
instance = new ErrorReporter();
}
return instance;
}
Only on android 1.5 calling the above method causes java.lang.VerifyError. I am not able to figure out why this is happening. Any hints on how to solve this problem
Simply do a build on 1.5 and you'll see where is the culprit...
I got exactly the same problem when i try to set the listadatper for a listview :)
check this
private void setResultListListAdapter() {
mListAdapter_ = new ListAdapter(mContext_,
R.layout.dsg_detailed_list_row, mLstStops_);
setListAdapter(mListAdapter_);
}
gets a VerifyError before mListAdapter_ gets initialized.. so something with this...
new ListAdapter(mContext_,
R.layout.dsg_detailed_list_row, mLstStops_);
but there's nothing which is just available in 1.5 :=//
strange thing...
also in 2 other classes this code works just fine... :=)
hope someone knowes more, thanks a lot!
(everything initialized, everything checked...setListAdapter never gets called)
SOLUTION (for me)
it really was a method which wasn't supported in Android 1.5
mConvertView_.setTag(uniqueIntID, ViewHolder);
ViewHolder is a static class, instead of using normal View.gettag(),
because of different layouts i was using the above method.. so :=)
the second is supported, View.getTag()
I was using a function in ErrorReporter class which was not available in 1.5. Used reflection to take care of the unavailable function and the error is gone.