API11 (and now12) and Spannable causing runtime NPE - android

Update 14th May
It's the mix of text sizes that breaks it, if I replace the
<item name = "android:textSize">16sp</item>
with just a change of colour like
<item name="android:textColor">#00ff00</item>
then it runs OK.
The references to TextLine,measure in the logcat should have given me a clue.
I'd still like to fix it though, I'm sure others will have a requirement for a mix of sizes in a single text line.
Udpdated 12 May - minimal code example is shown at the end of this post
Code which works fine under SDK 2.everything, throws a null pointer exception when run in a 3.0 emulator. I've narrowed it down to the only occurrence of a SpannableString in my code. I'm using this to put some text of differing font sizes in a banner area at the top of the screen. The logcat is:
FATAL EXCEPTION: main
java.lang.NullPointerException
at android.text.style.TextAppearanceSpan.updateDrawState(TextAppearanceSpan.java:209)
at android.text.TextLine.handleRun(TextLine.java:848)
at android.text.TextLine.measureRun(TextLine.java:399)
at android.text.TextLine.measure(TextLine.java:278)
at android.text.TextLine.metrics(TextLine.java:252)
at android.text.Layout.measurePara(Layout.java:1432)
at android.text.Layout.getDesiredWidth(Layout.java:89)
at android.text.Layout.getDesiredWidth(Layout.java:68)
at android.widget.TextView.onMeasure(TextView.java:5713)
at android.view.View.measure(View.java:10577)
at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:581)
at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:365)
at android.view.View.measure(View.java:10577)
at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:581)
at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:365)
at android.view.View.measure(View.java:10577)
at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:581)
at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:365)
at android.view.View.measure(View.java:10577)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4270)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:267)
at android.view.View.measure(View.java:10577)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:764)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:519)
at android.view.View.measure(View.java:10577)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4270)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:267)
at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:1876)
at android.view.View.measure(View.java:10577)
at android.view.ViewRoot.performTraversals(ViewRoot.java:885)
at android.view.ViewRoot.handleMessage(ViewRoot.java:1944)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:126)
at android.app.ActivityThread.main(ActivityThread.java:3997)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:491)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:841)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:599)
at dalvik.system.NativeStart.main(Native Method)
The code is in a handler called by a timer, it writes to a text view with the following essential lines (null checks etc omitted)
TextView tvBanner = (TextView) findViewById(R.id.RefText);
.....
int startSpan = altDispStr.indexOf("\n");
int endSpan = altDispStr.length();
spanRange = new SpannableString(altDispStr);
spanRange.setSpan(new TextAppearanceSpan(this,
R.style.custompoint), startSpan, endSpan,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
....
....
tvBanner.setText(spanRange);
When I trap it in the debugger (not easy with the 3.0 emulator and 3GB of RAM) it gets through the handler method OK, - spanRange is not null, but the NPE and FC happens sometime later in the main looper.
The textview (RefTxt) is in an xml called infobar.xml which is included in the main.xml. The infobar's essential components are:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/BannerRelView"
android:layout_alignParentTop="true"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:background="#800000ff"
android:layout_width="wrap_content">
<TextView
android:id="#+id/BannerOptionsButton"
android:layout_alignParentRight="true"
....
</TextView>
<TextView
android:id="#+id/BannerGPS"
android:layout_toLeftOf="#+id/BannerOptionsButton"
....
</TextView>
<TextView
android:id="#+id/RefText"
android:layout_toLeftOf="#+id/BannerGPS"
......
</TextView>
</RelativeLayout>
If I replace the SpannableString with a plain old String then the app runs in 3.0 emulators.
I'm wondering if there are any extra measures I need to take with Spannables and tablet devices?
When it dies, the debug perspective shows
- mt and tl are both not null
Update example
I've reduced this to the smallest code example which demonstrates the error, it's OK under 2.1 but crashes with the same NPE under 3.0
Activity code:
public class SpanTest extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
String dispStr = "I'm the first line\nI'm the second line";
TextView tvBanner = (TextView) findViewById(R.id.textView1);
int startSpan = dispStr.indexOf("\n");
int endSpan = dispStr.length();
Spannable spanRange = new SpannableString(dispStr);
spanRange.setSpan(new TextAppearanceSpan(this, R.style.custompoint), startSpan, endSpan, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
tvBanner.setText(spanRange);
}
}
main.xml is a LinearLayout containg just the one TextView. My styles.xml containing custompoint is:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style
name="custompoint">
<item name="android:textSize">24sp</item>
<item name="android:textStyle">bold</item>
</style>
</resources>
.

Your TextView is using a TextPaint object that doesn't have the linkColor set. I see the style/theme you are using is somehow not setting the linkColor. Try adding a linkColor to the style and see if that solves your problem.
EDIT: you should probably inherit the default style, and that will give you what you want. Not sure why the behavior changed from 2.1 to 3.0, but...

Related

What causes "RuntimeException: Binary XML file line #20: You must supply a layout_height attribute." (ActionBarScherlock is suspected)?

I have app with ActionBarScherlock and I use ACRA. I receive crash reports from some users with following error:
"java.lang.RuntimeException: Binary XML file line #20: You must supply a layout_height attribute.
at android.content.res.TypedArray.getLayoutDimension(TypedArray.java:491)
at android.view.ViewGroup$LayoutParams.setBaseAttributes(ViewGroup.java:3602)
at android.view.ViewGroup$LayoutParams.<init>(ViewGroup.java:3554)
at android.widget.AbsListView$LayoutParams.<init>(AbsListView.java:4322)
at android.widget.AbsListView.generateLayoutParams(AbsListView.java:4116)
at android.widget.AbsListView.generateLayoutParams(AbsListView.java:74)
at android.view.LayoutInflater.inflate(LayoutInflater.java:396)
at android.view.LayoutInflater.inflate(LayoutInflater.java:320)
at android.widget.ArrayAdapter.createViewFromResource(ArrayAdapter.java:332)
at android.widget.ArrayAdapter.getView(ArrayAdapter.java:323)
at android.webkit.WebTextView$AutoCompleteAdapter.getView(WebTextView.java:650)
at android.widget.AbsListView.obtainView(AbsListView.java:1430)
at android.widget.AutoCompleteTextView$DropDownListView.obtainView(AutoCompleteTextView.java:1548)
at android.widget.ListView.measureHeightOfChildren(ListView.java:1216)
at android.widget.AutoCompleteTextView.buildDropDown(AutoCompleteTextView.java:1376)
at android.widget.AutoCompleteTextView.showDropDown(AutoCompleteTextView.java:1140)
at android.widget.AutoCompleteTextView.updateDropDownForFilter(AutoCompleteTextView.java:1022)
at android.widget.AutoCompleteTextView.onFilterComplete(AutoCompleteTextView.java:1005)
at android.widget.Filter$ResultsHandler.handleMessage(Filter.java:285)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:130)
at android.app.ActivityThread.main(ActivityThread.java:3717)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:864)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:622)
at dalvik.system.NativeStart.main(Native Method)"
Of course I've tried to google it and found that it is most likely caused by ActionBarScherlock (and I noticed that every user who encountered with this error uses android 2.3.*) but haven't found a solution.
It's a bit disconcerting that I can't reproduce this error on my own 2.3.* device...
So, what causes this error?
In my case this was due to a problem with ActionBarsherlock.
In my Android manifest I had android:theme="#style/AppTheme"
then when you go to styles, i saw my AppTheme's parent was "AppBaseTheme". This was the problem!
<style name="AppTheme" parent="AppBaseTheme">
I changed this to
<style name="AppTheme" parent="Theme.Sherlock">
And my problem was solved.
One of our #1 crashes came from this issue, especially on ZTE devices. While the actionbar worked on most screens, we were getting this crash when users interacted with a Webview Edittext/InputBox. The crash happened as a result of autocomplete on the Webview. Disabling autocomplete seemed to eliminate the crashes. Why autocomplete should have anything to do with the Actionbar is still a mystery.
Here we disable the autocomplete just for ZTE devices. We may expand the list later if we have problems on other devices.
public static boolean disableWebViewAutoCompleteForDevicesThatCrash(WebView webView)
{
// We may add some other bizarre devices to this list if the ZTE fix works well.
if ("ZTE".equals(Build.MANUFACTURER))
{
webView.getSettings().setSaveFormData(false);
webView.clearFormData();
return true;
}
else
{
return false;
}
}
The layout_height in this instance is defined as ?attr/actionBarSize which is a theme attribute with a value of #dimen/action_bar_height that is defined in three places: values/, values-land/, and values-sw600dp/.
This is usually cased by OEMs who've tinkered with the resource system causing some aspect of this chain to not load correctly. There's nothing we can really do, as far as I'm aware.
I had same problem and solve it by change in AndroidManifest.xml. You have to set theme of particular Activity or complete application to Theme.Sherlock.Light (I think you can specify only Theme.Sherlock).
In code it will be:
<application
...
android:theme="#style/Theme.Sherlock.Light">
or
<activity
...
android:theme="#style/Theme.Sherlock.Light">

Null Pointer Exception-android.widget.onTouchEvent

I got the following crash report in the android market place. While testing I haven't found any crash and my app works fine. Once I published my app I got the following crash report which I have shown below.
But I am not able to find where the crash occurs, I checked in some stack overflow question and there in some cases I got that use of setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD); make cause crash in some devices. Is it true because in my app in some activity I have used this line of code in order to change the input type of EditText from password-text / text-password?
Please help me to solve this out.
Stack Trace
java.lang.NullPointerException
at android.widget.TextView.onTouchEvent(TextView.java:7529)
at android.view.View.dispatchTouchEvent(View.java:3933)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:906)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:906)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:906)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:906)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:906)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:906)
at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1877)
at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1211)
at android.app.Activity.dispatchTouchEvent(Activity.java:2198)
at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1852)
at android.view.ViewRoot.deliverPointerEvent(ViewRoot.java:2382)
at android.view.ViewRoot.handleMessage(ViewRoot.java:2010)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:150)
at android.app.ActivityThread.main(ActivityThread.java:4385)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:849)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:607)
at dalvik.system.NativeStart.main(Native Method)
<EditText
android:id="#+id/txt_edit_passwrd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/txt_passwrd_title"
android:background="#drawable/img_password_textbox"
android:cursorVisible="true"
android:layout_marginTop="195dp"
android:hint="#string/passwrd_hint_text"
android:inputType="textPassword"
android:maxLength="10"
android:padding="10dp"
android:textColor="#121212" >
</EditText>
NullPointerException in my own experience tends to mean it cannot find a reference object for instance the edit text your setting the input type for cannot be found, check your layout references and how you've declared the EditText itself.
First check , Have you mention Minimum_sdk_version in android-manifest?
if not then following may be the reason of crashing your application--
If you are using that functionality of android o.s that does not support on customer device.Say you are using Finger_Pointer(as MotionEvent.ACTION_POINTER_DOWN) which does not support before android 2.0.
Or you are using onBackPressed() which does not support for android 1.6.I just gave you hint you can check other issue like this if you have
Updated
For HTC device, TextView's property InputType.TYPE_CLASS_NUMBER lead to crash
Here is the same problem discussed you can refer to this also.
The Solution is not to use "setInputType" with a TextView. You don't need input type filtering for TextViews anyway since they are for displaying text only. Input type is only needed for EditText (and there it works). I had the same problem with Android versions below 4.2.
The disadvantage is, that applying input type "password" on a textview actually makes sense as it masks the password, which may be intended (it was in my case). But this causes random crashes when touching or scrolling over the textview.

Views in a RelativeLayout with MapView are null

I have a MapActivity with a mapview. It works fine. Now I want to add a SeekBar onto my MapView. It has to be at the bottom but on the mapview. User will scroll to set the distance. Whatever. My problem is, that any view I am trying to put there is null, when I reach them by findViewById().
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<com.google.android.maps.MapView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/mapview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:clickable="true"
android:apiKey="mykey"/>
<SeekBar
android:id="#+id/DistanceBar"
android:max="2000"
android:progress="2000"
android:layout_alignParentBottom="true"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="14dip"></SeekBar>
</RelativeLayout>
I am trying to reach that like this:
public class MyActivity extends MapActivity implements LocationListener {
...
SeekBar DistanceBar;
...
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mapView = (MapView) findViewById(R.id.mapview);
DistanceBar = (SeekBar) findViewById(R.id.DistanceBar); //This is afterwards null.
I have made a research everywhere and couldn't find a similar problem. Someone used something very similar. So I ignored that it is null, I didn't call the SeekBar in onCreate(). But the SeekBar hasn't been drawen at all. Can't I add other Views to a mapactivity?
Thanks for any idea!
An IMPORTANT EDIT: The graphical layout viewer shows the SeekBar as it should at the bottom of mapview.
I still get NullPointerException:
ERROR/AndroidRuntime(12738): FATAL EXCEPTION: main
ERROR/AndroidRuntime(12738): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.MyApps.MapLocations/com.MyApps.MapLocations.MyActivity}: java.lang.NullPointerException
ERROR/AndroidRuntime(12738): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2663)
ERROR/AndroidRuntime(12738): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
ERROR/AndroidRuntime(12738): at android.app.ActivityThread.access$2300(ActivityThread.java:125)
ERROR/AndroidRuntime(12738): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
ERROR/AndroidRuntime(12738): at android.os.Handler.dispatchMessage(Handler.java:99)
ERROR/AndroidRuntime(12738): at android.os.Looper.loop(Looper.java:123)
ERROR/AndroidRuntime(12738): at android.app.ActivityThread.main(ActivityThread.java:4627)
ERROR/AndroidRuntime(12738): at java.lang.reflect.Method.invokeNative(Native Method)
ERROR/AndroidRuntime(12738): at java.lang.reflect.Method.invoke(Method.java:521)
ERROR/AndroidRuntime(12738): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:871)
ERROR/AndroidRuntime(12738): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:629)
ERROR/AndroidRuntime(12738): at dalvik.system.NativeStart.main(Native Method)
ERROR/AndroidRuntime(12738): Caused by: java.lang.NullPointerException
ERROR/AndroidRuntime(12738): at com.MyApps.MapLocations.MyActivity.setupSeekbar(MyActivity.java:343)
ERROR/AndroidRuntime(12738): at com.MyApps.MapLocations.MyActivity.onCreate(MyActivity.java:89)
ERROR/AndroidRuntime(12738): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
ERROR/AndroidRuntime(12738): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
ERROR/AndroidRuntime(12738): ... 11 more
Here is the result from HierarchyViewer:
Can't I add other Views to a mapactivity?
Yes, you can.
Clean your project (Project -> Clean from the Eclipse main menu or ant clean at the command line). Then use Hierarchy View to see what is going on. It sounds like either your IDs are off kilter (in which case the clean will help) or perhaps you failed to save the XML or something.
I just have copied the main.xml file as map.xml and deleted main.xml. And it worked. I still don't understand why it happened. Maybe the "main" causes some problem. Maybe MapActivities have defined for themselves a "main" layout which is interrupting my "main" layout. But this was the solution somehow. Thanks a lot for your patience!
IMPORTANT EDIT: I have definitely found the problem. main.xml file remained in layout-normal and layout-normal-long folders without any SeekBar. I forgot to edit those.

Android: Applying an animation to a view creates RuntimeException

I am setting an animation on my view from following the ApiDemo example (see layout_grid_fade.html):
<?xml version="1.0" encoding="utf-8"?>
<gridLayoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
android:rowDelay="50%"
android:directionPriority="column"
android:animation="#anim/fade" />
and below is my code
mView.startAnimation(AnimationUtils.loadAnimation(ViewModel.this, R.anim.layout_grid_fade));
mView.setImage(modelImages.get(0).image);
but i get exception dont know why? below is my log trace
FATAL EXCEPTION: main
java.lang.RuntimeException: Unknown animation name: gridLayoutAnimation
at android.view.animation.AnimationUtils.createAnimationFromXml(AnimationUtils.java:116)
at android.view.animation.AnimationUtils.createAnimationFromXml(AnimationUtils.java:83)
at android.view.animation.AnimationUtils.loadAnimation(AnimationUtils.java:64)
at nick.kimK.ViewModel$1$1.run(ViewModel.java:72)
at android.os.Handler.handleCallback(Handler.java:587)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:123)
at android.app.ActivityThread.main(ActivityThread.java:4627)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:521)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:871)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:629)
at dalvik.system.NativeStart.main(Native Method)
UPD:
Not every xml in res/anim folder declares an animation. Some of them might declare Animators or LayoutAnimationControllers. Those are not Animations, thus they can't be loaded with the loadAnimation() call.
--
It looks like the gridLayoutAnimation tag describes not a particular basic animation type but rather a GridLayoutAnimationController. So it can be loaded directly with AnimationUtils.loadAnimation() but rather should be set to a ViewGroup (a layout) throuh layoutAnimation property. If you still want to obtain the AnimationController instance in code, use AnimationUtils.loadLayoutAnimation() method:
LayoutAnimationController layoutAnimation = AnimationUtils.loadLayoutAnimation(ViewModel.this, R.anim.layout_grid_fade)
But you hardly can use the layoutAnimation in the way you're doing in your example.
I found this article quite useful for understanding the layout animations.

TextView inside a LinearLayout, crash with a long string

Using Android, here is part of a layout xml file:
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:textColor="#191919">
<TextView android:id="#+id/someTextField"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textStyle="bold" />
<TextView android:id="#+id/anotherTextField"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1" />
</LinearLayout>
I am adding this view (at runtime) to a ViewAnimator like this:
ViewAnimator viewAnimator = (ViewAnimator)findViewById(R.id.viewAnimator);
View newView = View.inflate(this, R.layout.new_view, null);
viewAnimator.addView(newView);
viewAnimator.showNext();
String newValue = "new value for the text field";
findViewById(R.id.deal_view).setVisibility(View.VISIBLE);
TextView someTextField = (TextView)findViewById(R.id.someTextField);
someTextField.setText(newValue);
This seems to be working fine, but when newValue is long enough to take more than 1 line of text in the layout, I am getting a crash:
09-06 21:36:48.208: ERROR/AndroidRuntime(6561): Uncaught handler: thread main exiting due to uncaught exception
09-06 21:36:48.248: ERROR/AndroidRuntime(6561): java.lang.StackOverflowError
09-06 21:36:48.248: ERROR/AndroidRuntime(6561): at android.view.ViewGroup.drawChild(ViewGroup.java:1486)
09-06 21:36:48.248: ERROR/AndroidRuntime(6561): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1228)
(many more lines like this)
Is this enough information to see what I might be doing wrong? It works perfectly fine when newValue is short enough for one line. I've thought about trying a TableLayout but it seems like this is exactly what a LinearLayout is good for.
Thanks for the help in the comments. I ended up taking the advice here (dropping ViewAnimator directly and using ViewFlipper). Better app, but still the same problem. I dropped one level of LinearLayout containers and it started working fine.
I'm assuming bhatt4982 is right, UI depth was too great.
bhatt4982, post your comment as an answer to get credit for this.

Categories

Resources