我的应用程序在5.0+设备上运行良好,但在旧设备(OS 4.4.4)上崩溃,并显示一个错误,我无法将其隔离到我的代码中(堆栈中没有对我的项目类的引用)。对我来说似乎很奇怪,这是设备特定的(如果这是代码错误,它将在任何地方崩溃)
我已经尝试过以下操作,但没有帮助: - 查看我所有的XML和Java,确保我没有将0设置为任何视图的任何维度 - 确保我没有在任何地方设置填充 - 删除了所有边距(只是为了检查-没有帮助,添加回来) - 删除所有的setBackground()方法(没有帮助) - 删除所有高程和半径属性 - 将所有CardView设置为Visibility.GONE(即使所有CardView都没有被绘制,仍会崩溃)
这个崩溃来自AOSP中的一个类:https://android.googlesource.com/platform/frameworks/support/+/master/v7/cardview/eclair-mr1/android/support/v7/widget/RoundRectDrawableWithShadow.java 我看到了一个相关的已打开的Bug(但未被分配):https://code.google.com/p/android/issues/detail?id=157919有趣的是,这个bug说明这在4.3上没有崩溃,但我手头没有这个设备。
关于如何调试此崩溃原因的建议:
E/AndroidRuntime( 708): java.lang.IllegalArgumentException: radius must be > 0
E/AndroidRuntime( 708): at android.graphics.RadialGradient.<init>(RadialGradient.java:53)
E/AndroidRuntime( 708): at android.support.v7.widget.RoundRectDrawableWithShadow.buildShadowCorners(RoundRectDrawableWithShadow.java:285)
E/AndroidRuntime( 708): at android.support.v7.widget.RoundRectDrawableWithShadow.buildComponents(RoundRectDrawableWithShadow.java:307)
E/AndroidRuntime( 708): at android.support.v7.widget.RoundRectDrawableWithShadow.draw(RoundRectDrawableWithShadow.java:209)
E/AndroidRuntime( 708): at android.view.View.draw(View.java:15493)
E/AndroidRuntime( 708): at android.widget.FrameLayout.draw(FrameLayout.java:472)
E/AndroidRuntime( 708): at android.view.View.getDisplayList(View.java:14402)
E/AndroidRuntime( 708): at android.view.View.getDisplayList(View.java:14444)
E/AndroidRuntime( 708): at android.view.View.draw(View.java:15222)
E/AndroidRuntime( 708): at android.view.ViewGroup.drawChild(ViewGroup.java:3340)
E/AndroidRuntime( 708): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3176)
E/AndroidRuntime( 708): at android.view.View.getDisplayList(View.java:14397)
E/AndroidRuntime( 708): at android.view.View.getDisplayList(View.java:14444)
E/AndroidRuntime( 708): at android.view.View.draw(View.java:15222)
E/AndroidRuntime( 708): at android.view.ViewGroup.drawChild(ViewGroup.java:3340)
E/AndroidRuntime( 708): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3176)
E/AndroidRuntime( 708): at android.view.View.draw(View.java:15511)
E/AndroidRuntime( 708): at android.widget.FrameLayout.draw(FrameLayout.java:472)
E/AndroidRuntime( 708): at android.support.v4.widget.NestedScrollView.draw(NestedScrollView.java:1679)
E/AndroidRuntime( 708): at android.view.View.getDisplayList(View.java:14402)
E/AndroidRuntime( 708): at android.view.View.getDisplayList(View.java:14444)
E/AndroidRuntime( 708): at android.view.View.draw(View.java:15222)
E/AndroidRuntime( 708): at android.view.ViewGroup.drawChild(ViewGroup.java:3340)
E/AndroidRuntime( 708): at android.support.design.widget.CoordinatorLayout.drawChild(CoordinatorLayout.java:1040)
E/AndroidRuntime( 708): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3176)
E/AndroidRuntime( 708): at android.view.View.getDisplayList(View.java:14397)
E/AndroidRuntime( 708): at android.view.View.getDisplayList(View.java:14444)
E/AndroidRuntime( 708): at android.view.View.draw(View.java:15222)
E/AndroidRuntime( 708): at android.view.ViewGroup.drawChild(ViewGroup.java:3340)
E/AndroidRuntime( 708): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3176)
E/AndroidRuntime( 708): at android.view.View.draw(View.java:15511)
E/AndroidRuntime( 708): at android.widget.FrameLayout.draw(FrameLayout.java:472)
E/AndroidRuntime( 708): at android.view.View.getDisplayList(View.java:14402)
E/AndroidRuntime( 708): at android.view.View.getDisplayList(View.java:14444)
E/AndroidRuntime( 708): at android.view.View.draw(View.java:15222)
E/AndroidRuntime( 708): at android.view.ViewGroup.drawChild(ViewGroup.java:3340)
E/AndroidRuntime( 708): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3176)
E/AndroidRuntime( 708): at android.view.View.getDisplayList(View.java:14397)
E/AndroidRuntime( 708): at android.view.View.getDisplayList(View.java:14444)
E/AndroidRuntime( 708): at android.view.View.draw(View.java:15222)
E/AndroidRuntime( 708): at android.view.ViewGroup.drawChild(ViewGroup.java:3340)
E/AndroidRuntime( 708): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3176)
E/AndroidRuntime( 708): at android.view.View.getDisplayList(View.java:14397)
E/AndroidRuntime( 708): at android.view.View.getDisplayList(View.java:14444)
E/AndroidRuntime( 708): at android.view.View.draw(View.java:15222)
E/AndroidRuntime( 708): at android.view.ViewGroup.drawChild(ViewGroup.java:3340)
E/AndroidRuntime( 708): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3176)
E/AndroidRuntime( 708): at android.view.View.getDisplayList(View.java:14397)
E/AndroidRuntime( 708): at android.view.View.getDisplayList(View.java:14444)
E/AndroidRuntime( 708): at android.view.View.draw(View.java:15222)
E/AndroidRuntime( 708): at android.view.ViewGroup.drawChild(ViewGroup.java:3340)
E/AndroidRuntime( 708): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3176)
E/AndroidRuntime( 708): at android.view.View.draw(View.java:15511)
E/AndroidRuntime( 708): at android.widget.FrameLayout.draw(FrameLayout.java:472)
E/AndroidRuntime( 708): at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:2623)
E/AndroidRuntime( 708): at android.view.View.getDisplayList(View.java:14402)
E/AndroidRuntime( 708): at android.view.View.getDisplayList(View.java:14444)
E/AndroidRuntime( 708): at android.view.HardwareRenderer$GlRenderer.buildDisplayList(HardwareRenderer.java:1597)
E/AndroidRuntime( 708): at android.view.HardwareRenderer$GlRenderer.draw(HardwareRenderer.java:1469)
E/AndroidRuntime( 708): at android.view.ViewRootImpl.draw(ViewRootImpl.java:2800)
E/AndroidRuntime( 708): at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2666)
E/AndroidRuntime( 708): at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2234)
E/AndroidRuntime( 708): at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1267)
E/AndroidRuntime( 708): at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6638)
E/AndroidRuntime( 708): at android.view.Choreographer$CallbackRecord.run(Choreographer.java:813)
E/AndroidRuntime( 708): at android.view.Choreogra
我的活动:
public class PaymentActivity extends AppCompatActivity {
public static final String XTRA_DEVICENAME = "";
private static String deviceName;
private ItemDto deviceDto;
private Activity mActivity;
private OkHttpClient okclient;
//Views
private RelativeLayout infoLayout;
private TextView deviceOwner;
private TextView devicePrice;
private TextView deviceInfo;
private TextView payDurationTitle;
private TextView payPriceTitle;
private TextView payDurationText;
private TextView payPriceText;
private Button upBtn;
private Button downBtn;
private TextView incText;
private View incrDivider;
private FloatingActionButton fab;
private ProgressBar devInfoProgress;
private LinearLayout incrBtnView;
private int mIterVal = 1;
private Constants.ColorInfo colorTheme = Constants.ColorInfo.GREY;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mActivity = this;
Intent intent = getIntent();
deviceName = intent.getStringExtra(XTRA_DEVICENAME);
setTheme(ColorUtil.getThemeForDevice(deviceName));
colorTheme = ColorUtil.getColorTheme(deviceName);
setContentView(R.layout.act_payment);
final Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onBackPressed();
}
});
okclient = new OkHttpClient();
CollapsingToolbarLayout collapsingToolbar =
(CollapsingToolbarLayout) findViewById(R.id.collapsing_toolbar);
collapsingToolbar.setTitle(deviceName.toUpperCase());
okclient = new OkHttpClient();
final ImageView imageView = (ImageView) findViewById(R.id.backdrop);
// todo get better default image
final String paymentIconUrl = "http://xxx/" + deviceName + "_lg.png";
Glide.with(mActivity)
.load(paymentIconUrl)
.diskCacheStrategy(DiskCacheStrategy.ALL)
.placeholder(R.drawable.ic_logo_allwhite)
.error(R.drawable.ic_logo_allwhite)
.into(imageView);
setupViews();
new GetItemInfoTask().execute(deviceName);
}
private void setupViews() {
infoLayout = (RelativeLayout) findViewById(R.id.device_info_layout);
infoLayout.setBackgroundColor(getResources().getColor(ColorUtil.getDeviceColor(deviceName, ColorUtil.COLOR_SECONDARY)));
incrBtnView = (LinearLayout) findViewById(R.id.incr_btn_view);
deviceOwner = (TextView) findViewById(R.id.info_owner);
devicePrice = (TextView) findViewById(R.id.info_price);
deviceInfo = (TextView) findViewById(R.id.info_max_amount);
payDurationTitle = (TextView) findViewById(R.id.paidDurationTitle);
payPriceTitle = (TextView) findViewById(R.id.paidAmountTitle);
payDurationText = (TextView) findViewById(R.id.paidDurationText);
payPriceText = (TextView) findViewById(R.id.paidAmountText);
devInfoProgress = (ProgressBar) findViewById(R.id.devinfo_progress);
devInfoProgress.getIndeterminateDrawable().setColorFilter(getResources().getColor(R.color.card_white), android.graphics.PorterDuff.Mode.MULTIPLY);
Drawable tmpDrawable = ColorUtil.getTintedDrawable(mActivity, R.drawable.ic_attach_money, colorTheme.getSecondary());
payPriceTitle.setCompoundDrawablesWithIntrinsicBounds(tmpDrawable, null, null, null);
Drawable tmpDrawable2 = ColorUtil.getTintedDrawable(mActivity, R.drawable.ic_clock, colorTheme.getSecondary());
payDurationTitle.setCompoundDrawablesWithIntrinsicBounds(tmpDrawable2, null, null, null);
upBtn = (Button) findViewById(R.id.pay_inc_up_btn);
downBtn = (Button) findViewById(R.id.pay_inc_down_btn);
incText = (TextView) findViewById(R.id.pay_inc_text);
incrDivider = (View) findViewById(R.id.iter_divider);
upBtn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
...
}
});
downBtn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
...
}
});
upBtn.setBackground(mActivity.getResources().getDrawable(colorTheme.getSelectorId()));
downBtn.setBackground(mActivity.getResources().getDrawable(colorTheme.getSelectorId()));
fab = (FloatingActionButton) findViewById((R.id.pay_fab_btn));
//TODO - manually coloring FAB, should do with color state list
fab.setEnabled(false);
fab.setBackgroundTintList(ColorStateList.valueOf(getResources().getColor(R.color.grey_300)));
fab.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
fab.setBackgroundTintList(ColorStateList.valueOf(getResources().getColor(R.color.card_white)));
...
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_payment, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
private class GetItemInfoTask extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... params) {
...
return null;
}
@Override
protected void onPostExecute(String result) {
...
}
@Override
protected void onPreExecute() {
devInfoProgress.setVisibility(View.VISIBLE);
}
@Override
protected void onProgressUpdate(Void... values) {
}
}
}
我的Layout.xml文件:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:card_view="http://schemas.android.com/tools"
android:id="@+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="@dimen/payments_backdrop_height"
android:fitsSystemWindows="true"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleMarginEnd="64dp"
app:expandedTitleMarginStart="48dp"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<ImageView
android:id="@+id/backdrop"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:scaleType="centerCrop"
android:transitionName="device_img"
app:layout_collapseMode="parallax" />
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/grey_200"
android:orientation="vertical">
<RelativeLayout
android:id="@+id/device_info_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/info_owner"
style="@style/DeviceInfo" />
<TextView
android:id="@+id/info_price"
style="@style/DeviceInfo"
android:layout_below="@+id/info_owner"/>
<TextView
android:id="@+id/info_max_amount"
style="@style/DeviceInfo"
android:layout_below="@+id/info_price"
android:layout_marginBottom="@dimen/grid1" />
<ProgressBar
android:id="@+id/devinfo_progress"
style="?android:attr/progressBarStyleLarge"
android:layout_width="@dimen/rythm48"
android:layout_height="@dimen/rythm48"
android:layout_toRightOf="@+id/info_price"
android:layout_marginRight="@dimen/grid5"
android:layout_marginTop="@dimen/grid1"
android:visibility="gone" />
</RelativeLayout>
<android.support.v7.widget.CardView
android:id="@+id/device_info_card"
style="@style/CardView"
card_view:cardCornerRadius="4dp"
card_view:cardElevation="6dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/launch_title"
style="@style/CardTitle"
android:text="Current Amounts" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/confirm_text"
android:layout_marginBottom="@dimen/grid5"
android:orientation="horizontal"
android:weightSum="2">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical">
<TextView
android:id="@+id/paidAmountTitle"
style="@style/TextAppearance.AppCompat.Medium"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableLeft="@drawable/ic_dollar"
android:gravity="center"
android:text="@string/paid_amount_title" />
<TextView
android:id="@+id/paidAmountText"
style="@style/TextAppearance.AppCompat.Headline"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical">
<TextView
android:id="@+id/paidDurationTitle"
style="@style/TextAppearance.AppCompat.Medium"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableLeft="@drawable/ic_clock"
android:gravity="center"
android:text="@string/paid_duration_title" />
<TextView
android:id="@+id/paidDurationText"
style="@style/TextAppearance.AppCompat.Headline"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>
<View
android:id="@+id/iter_divider"
android:layout_width="wrap_content"
android:layout_height="1dp"
android:layout_marginBottom="@dimen/grid2"
android:layout_marginTop="@dimen/grid_5"
android:background="@color/grey_400"
android:visibility="gone"/>
<LinearLayout
android:id="@+id/incr_btn_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/grid5"
android:layout_marginLeft="@dimen/grid4"
android:layout_marginRight="@dimen/grid4"
android:orientation="horizontal"
android:gravity="center"
android:weightSum="3"
android:visibility="gone">
<Button
android:id="@+id/pay_inc_down_btn"
style="@style/InfoButton"
android:layout_width="@dimen/rythm48"
android:layout_height="@dimen/rythm48"
android:text="-"
android:textSize="32sp"
android:layout_weight="1"/>
<TextView
android:id="@+id/pay_inc_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="1"
android:gravity="center"
android:layout_marginRight="@dimen/grid2"
android:layout_marginLeft="@dimen/grid2"
android:textSize="24sp"
android:layout_weight="1"/>
<Button
android:id="@+id/pay_inc_up_btn"
style="@style/InfoButton"
android:layout_width="@dimen/rythm48"
android:layout_height="@dimen/rythm48"
android:text="+"
android:textSize="32sp"
android:layout_weight="1"/>
</LinearLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
<android.support.v7.widget.CardView
android:id="@+id/provider_card_view"
style="@style/CardView"
card_view:cardCornerRadius="4dp"
card_view:cardElevation="6dp">
<fragment
android:id="@+id/provider_fragment"
android:name="com.cleartoken.pay.ui.frag.ProviderFragment"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</android.support.v7.widget.CardView>
<android.support.v7.widget.CardView
style="@style/CardView"
card_view:cardCornerRadius="4dp"
card_view:cardElevation="6dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Info"
android:textAppearance="@style/TextAppearance.AppCompat.Title" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/long_text" />
</LinearLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
<android.support.design.widget.FloatingActionButton
android:id="@+id/pay_fab_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/grid2"
android:clickable="true"
android:src="@drawable/ic_fab_enabled"
app:borderWidth="0dp"
app:layout_anchor="@id/device_info_card"
app:layout_anchorGravity="bottom|right|end" />
</android.support.design.widget.CoordinatorLayout>
CardView的样式.xml片段:
<style name="CardView">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_gravity">center</item>
<item name="android:layout_margin">@dimen/grid1</item>
</style>
注意:
我普遍使用相同的卡片样式。在Act#1上,这是有效的*(在那个Act#1中没有协调布局,这是一个很大的区别)。
我的卡片XML在各处都是这样的:
<android.support.v7.widget.CardView
android:id="@+id/device_info_card"
style="@style/CardView"
card_view:cardCornerRadius="4dp"
card_view:cardElevation="6dp">