NPE in Android WebView - android

I'm getting a NullPointerException on the following call in Android 2.3.4:
java.lang.NullPointerException
at android.webkit.WebView.addPackageNames(WebView.java:4063)
at com.my.company.MyClass$MyInnerClass.myMethod(MyClass.java:283)
at android.webkit.BrowserFrame.stringByEvaluatingJavaScriptFromString(Native Method)
at android.webkit.BrowserFrame.stringByEvaluatingJavaScriptFromString(Native Method)
at android.webkit.BrowserFrame.loadUrl(BrowserFrame.java:246)
at android.webkit.WebViewCore.loadUrl(WebViewCore.java:1981)
at android.webkit.WebViewCore.access$1400(WebViewCore.java:53)
at android.webkit.WebViewCore$EventHub$1.handleMessage(WebViewCore.java:1122)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:130)
at android.webkit.WebViewCore$WebCoreThread.run(WebViewCore.java:674)
at java.lang.Thread.run(Thread.java:1019)
MyClass$MyInnerClass is added to the JavaScript interface as
class MyClass {
// ...
myWebView.addJavascriptInterface(new MyInnerClass(), "MyInnerClass");
// ...
public void myOuterMethod(int param1, int param2) {
// Notify a listener that myOuterMethod was called
}
private class MyInnerClass {
public void myMethod(int param1, int param2) {
myOuterMethod(param1, param2);
}
}
}
So, the JavaScript call MyInnerClass.myMethod(-1, -1) seems to come over the Java-JavaScript bridge fine, but fails in the addPackageNames call, which isn't my code.
I've looked at the android.webkit.WebView class in GrepCode, but I can't figure out how I could have caused this. The only line in addPackageNames is
public void addPackageNames(Set<String> packageNames) {
mWebViewCore.sendMessage(EventHub.ADD_PACKAGE_NAMES, packageNames);
}
So, I've come to the conclusion that either mWebViewCore or EventHub is null.
Can any Android experts shed some light on this? Is this a known bug? Did I cause this? If so, how? If not, how might I prevent this?

This is definitelly related to the mWebViewCore being set to null.
mWebViewCore is instantiated inside of the ViewView's constructor. And the only place where it is set to null is a public method destroy().
Do you call webView.destroy() anywhere in the code?

It seems to me that your problem is that the outer class has not been instantiated when your myMethod is called. What's a bit interesting here is that the internal code that seems to be breaking in your case is no longer there in the Android 4.0 source code - so your issue might not occur on that version of Android. To me this also indicates that there were some issues with the previous version of Android Webview and perhaps you are encountering an issue with Android. But that's just speculation, my experience usually is that I'm doing something wrong, not the Android team :)
What could be a solution would be to wrap your code in an if statement:
if(MyClass.this != null) {
myOuterMethod(param1, param2);
}
This is not a beautiful solution but if it works I think it won't break anything.

Related

XmlPullParserException: Meta-data does not start with input-method tag (Android custom keyboard)

While working on another project, I noticed an exception pop up in logcat for a previous test keyboard I had made (based on the Going On section of this answer). It is installed on my phone, but it was not the project I was currently running.
XmlPullParserException: Meta-data does not start with input-method tag
I retested the keyboard and it still works, so it doesn't seem to be a big problem. However I don't like to leave errors if I can help it.
I couldn't find any other SO questions related to this but I did find where it is called in the source code for InputMethodInfo:
String nodeName = parser.getName();
if (!"input-method".equals(nodeName)) {
throw new XmlPullParserException(
"Meta-data does not start with input-method tag");
}
What would cause this error to happen?
Supplemental Code
InputMethodService
public class WodeInputMethodService extends InputMethodService implements ImeContainer.OnSystemImeListener {
#Override
public View onCreateInputView() {
LayoutInflater inflater = getLayoutInflater();
ImeContainer jianpan = (ImeContainer) inflater.inflate(R.layout.jianpan_yangshi,
null, false);
jianpan.showSystemKeyboardsOption("ᠰᠢᠰᠲ᠋ᠧᠮ");
jianpan.setOnSystemImeListener(this);
return jianpan;
}
#Override
public InputConnection getInputConnection() {
return getCurrentInputConnection();
}
#Override
public void onChooseNewSystemKeyboard() {
InputMethodManager im = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
if (im == null) return;
im.showInputMethodPicker();
}
}
The error is probably hiding deeper than this (like in the custom keyboard view or the library keyboard that it is inherited from), but because of the amount of code involved, I am asking a basic question first. If I find the answer or more relevant code, I will post an update.
Stack trace
04-26 10:30:13.466 855-880/? A/InputMethodManagerService: Unable to load input method ComponentInfo{net.studymongolian.jianpan/net.studymongolian.jianpan.WodeInputMethodService}
org.xmlpull.v1.XmlPullParserException: Meta-data does not start with input-method tag
at android.view.inputmethod.InputMethodInfo.<init>(InputMethodInfo.java:162)
at com.android.server.InputMethodManagerService.buildInputMethodListLocked(InputMethodManagerService.java:2732)
at com.android.server.InputMethodManagerService$MyPackageMonitor.onSomePackagesChanged(InputMethodManagerService.java:554)
at com.android.internal.content.PackageMonitor.onReceive(PackageMonitor.java:402)
at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:863)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.os.HandlerThread.run(HandlerThread.java:61)
Notes
This unfortunately isn't an MCVE question because I can't reproduce the problem. I also don't know the exact part of the code that is causing the problem. I am still asking the question, though, because someone familiar with the error could describe a specific situation that causes it.

Android cordova chromeview : Not implemented reached in virtual quota::SpecialStoragePolicy

I'm working on a phonegap project which contains a canvas overlayed with kinetic.js, which allows a user to pinch zoom and pan around an image, then draw annotations on it. it works spliendidly in a browser and on windows and apple tablets, but of course android is a good bit slower.
as a solution, i've released the app using https://github.com/thedracle/cordova-android-chromeview. after switching my main java class to use ChromeView as the webview, i'm getting this error on startup:
12-03 13:21:09.083: E/chromium(13917): [ERROR:aw_browser_context.cc(191)] Not implemented reached in virtual quota::SpecialStoragePolicy* android_webview::AwBrowserContext::GetSpecialStoragePolicy()
after debugging through the codebase, it looks like the error is triggering here:
private void setNativeContentsClientBridge(int nativeContentsClientBridge) {
mNativeContentsClientBridge = nativeContentsClientBridge;
}
(AwContentsClientBridge.java line 36).
i'm trying to find out what the nativeContentsClientBridge int is. My value is 1611312352 but i haven't a notion of what that represents.
my gut feel is that the chromium browser is missing an implementation for accessing localstorage. i found this bug:
https://github.com/pwnall/chromeview/issues/27
where someone is experiencing the same thing, but there is no solution.
for assistance, this is my main activity class:
package com.companion;
import org.apache.cordova.Config;
import org.apache.cordova.CordovaActivity;
import us.costan.chrome.ChromeSettings;
import us.costan.chrome.ChromeView;
import android.os.Bundle;
public class CompanionApp extends CordovaActivity
{
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState)
{
ChromeView chromeView = new ChromeView(CompanionApp.this);
ChromeSettings settings = chromeView.getSettings();
settings.setJavaScriptEnabled(true);
settings.setDatabaseEnabled(true);
settings.setDomStorageEnabled(true);
setContentView(chromeView);
super.loadUrl(Config.getStartUrl());
}
}
Thanks for your help,
Margaret
Don't know if it's normal, but it seems that a method's not implemented in Chromium base code : https://github.com/01org/pa-chromium/blob/master/android_webview/browser/aw_browser_context.cc
Here's that particular method:
quota::SpecialStoragePolicy* AwBrowserContext::GetSpecialStoragePolicy() {
// TODO(boliu): Implement this so we are not relying on default behavior.
NOTIMPLEMENTED();
return NULL;
}
I hope it helps :)

Find out if WebView has been destroyed

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.

Android: NoClassDefError occurs in <4.0 but not >=4.0?

I am trying to launch a new intent from my Activity, but I get a NoClassDefFoundError. The exception occurs resolving MyClassB.class. Oddly I can resolve other classes, and the error only occurs in android versions 2.2 and 2.3, it works fine in 4.0+.
Both the class that causes the error and the other classes that resolve successfully are in the same package as the Activity where the code is executing. Basically, the below code gives the below error on 2.2/2.3, but works fine on 4.0+. I have also tried using the full package name like: com.me.MyClassB.class, but get the same error.
I realized this question is pretty vague, but am thoroughly confused and hoping that somebody might be able to help.
package com.me;
public class MyActivity extends Activity
{
protected onCreate(Bundle bundle)
{
super.onCreat(bundle);
Class a = MyClassA.class;
Class b = MyClassB.class;
}
}
01-17 10:37:36.473: E/AndroidRuntime(1976): java.lang.NoClassDefFoundError: com.me.MyClassB
I'm not sure if this is the problem but in your onCreate method you need to add super.onCreate(bundle) at the beginning e.g.
protected onCreate(Bundle bundle)
{
super.onCreate(bundle);
Class a = MyClassA.class;
Class b = MyClassB.class;
}
This was caused because MyClassB.class implements ActionBar.OnNavigationListener. It seems if classes contain certain code for a higher api level, they don't get setup properly at runtime, resulting in these sorts of errors. I expecteded MyClassB.class to crash on 2.3, but the NoClassDefFoundError was particularly mystifying.

Android java.lang.VerifyError only on 1.5

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.

Categories

Resources