安卓开发中遇到的奇奇怪怪的问题

原创 2016年09月25日 12:49:21

写这篇文章属于脑中一闪的一个念头,是想着把自己做项目中遇到的一些奇怪问题和解决办法分享出来。因为是现想,所以想到一个在更新一个吧。可能有理解错误的地方,望指出。

1.App的首次安装。

问题描述:在我们安装完成一个app时,在安装界面直接点击打开。我们进入了app的首页,这时我们按home键返回桌面,再点击应用图标,会发现没有直接进入首页,而是先进入了app的闪屏页,在进入首页。重复这一步一直如此。这时我们按back键返回,发现没有直接退回桌面,而是返回到之前打开的多个首页。但是如果一开始安装完我们不是直接打开,而是在桌面点击应用进入就不会这样了。

奇奇怪怪~~

记得当时我在应用市场下载了部分应用,也有一些有同样的问题。但是有些虽然重复打开,但双击退出程序将整个重复打开的关闭了。这确实也是一种方法,但是觉得不是最合理。

解决方法:

  1. https://code.google.com/p/android/issues/detail?id=2373#c40
  2. http://stackoverflow.com/questions/3042420/home-key-press-behaviour/4782423#4782423

我贴一下代码

if (!isTaskRoot()) {
            Intent intent = getIntent();
            String action = intent.getAction();
            if (intent.hasCategory(Intent.CATEGORY_LAUNCHER) && action != null && action.equals(Intent.ACTION_MAIN)) {
                finish();
                return;
            }
        }

2.Android自定义CheckBox

问题描述:曾经写过一个自定义CheckBox,结果运行在4.1的手机上消失不见了。。。你说郁闷不。写法如下:

<CheckBox
      android:id="@+id/check_box"
      style="@style/MyCheckBox"
      android:layout_width="wrap_content"
      android:layout_height="match_parent"/>
<style name="MyCheckBox" parent="Widget.AppCompat.CompoundButton.CheckBox">
        <item name="android:button">@drawable/checkbox_selector</item>
</style>
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/icon_on" android:state_checked="true"/>
 <!-- 设置选中图片 -->
    <item android:drawable="@drawable/icon_off" android:state_checked="false"/>
 <!-- 设置未选中图片 -->
</selector>

写法没有什么问题吧,但是就是不显示,凭空消失。当然如果我加上文字,就出来了,但是文字图片重叠。。。

最后谷歌出了原因:大致是说4.1.2版本中CompoundButton没有getCompoundPaddingXX。两个版本的计算方式不一样,4.1.2以上版本绘制文字时,会把图片的宽度和paddingXX的宽度加上,而4.1.2版本只计算设置的paddingLeft。

知道了原因,解决方法:

<style name="MyCheckBox" parent="Widget.AppCompat.CompoundButton.CheckBox">
        <item name="android:button">@null</item>
        <item name="android:paddingLeft">0dp</item>
        <item name="android:drawableLeft">@drawable/checkbox_selector</item>
</style>

3. RecyclerView Bug

问题描述:这个是在友盟的错误分析中报的,错误信息如下:

java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid view holder adapter positionViewHolder{42fb7f40 position=11 id=-1, oldPos=-1, pLpos:-1 no parent}
    at android.support.v7.widget.RecyclerView$Recycler.validateViewHolderForOffsetPosition(RecyclerView.java:4801)
    at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:4932)
    at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:4913)
    at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2029)
    at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1414)
    at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1377)
    at android.support.v7.widget.LinearLayoutManager.scrollBy(LinearLayoutManager.java:1193)
    at android.support.v7.widget.LinearLayoutManager.scrollVerticallyBy(LinearLayoutManager.java:1043)
    at android.support.v7.widget.RecyclerView.scrollByInternal(RecyclerView.java:1552)
    at android.support.v7.widget.RecyclerView.onTouchEvent(RecyclerView.java:2649)
    at android.view.View.dispatchTouchEvent(View.java:7706)
    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2224)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1954)
    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2230)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1968)
    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2230)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1968)
    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2230)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1968)
    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2230)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1968)
    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2230)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1968)
    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2230)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1968)
    at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2074)
    at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1521)
    at android.app.Activity.dispatchTouchEvent(Activity.java:2569)
    at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2022)
    at android.view.View.dispatchPointerEvent(View.java:7886)
    at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:3967)
    at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:3846)
    at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3412)
    at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3462)
    at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3431)
    at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3538)
    at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3439)
    at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3595)
    at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3412)
    at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3462)
    at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3431)
    at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3439)
    at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3412)
    at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:5552)
    at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:5532)
    at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:5503)
    at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:5632)
    at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:185)
    at android.view.InputEventReceiver.nativeConsumeBatchedInputEvents(Native Method)
    at android.view.InputEventReceiver.consumeBatchedInputEvents(InputEventReceiver.java:176)
    at android.view.ViewRootImpl.doConsumeBatchedInput(ViewRootImpl.java:5605)
    at android.view.ViewRootImpl$ConsumeBatchedInputRunnable.run(ViewRootImpl.java:5651)
    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:761)
    at android.view.Choreographer.doCallbacks(Choreographer.java:574)
    at android.view.Choreographer.doFrame(Choreographer.java:542)
    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:747)
    at android.os.Handler.handleCallback(Handler.java:733)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:136)
    at android.app.ActivityThread.main(ActivityThread.java:5162)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:515)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:602)

从上面可以看到并没有报到我们自己的代码里面来,这就很尴尬了。老办法谷歌,找到了Drakeet大神的一篇博客,说到了我的心坎里。

重现的方法是:使用 RecyclerView 加官方下拉刷新的时候,如果绑定的 List 对象在更新数据之前进行了 clear,而这时用户紧接着迅速上滑 RV,就会造成崩溃,而且异常不会报到你的代码上,属于RV内部错误。初次猜测是,当你 clear 了 list 之后,这时迅速上滑,而新数据还没到来,导致 RV 要更新加载下面的 Item 时候,找不到数据源了,造成 crash.

真是一样一样的,那么解决方法大神也提供了,就是在刷新,也就是 clear 的同时,让 RecyclerView 暂时不能够滑动,之后再允许滑动即可。代码就是在 RecyclerView 初始化的时候加上是否在刷新进而拦截手势:

mRecyclerView.setOnTouchListener(
        new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (mIsRefreshing) {
                    return true;
                } else {
                    return false;
                }
            }
        }
);

当然如果觉得刷新时不能滑动可以用这种方案

public class WrapContentLinearLayoutManager extends LinearLayoutManager {
    //... constructor
    @Override
    public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
        try {
            super.onLayoutChildren(recycler, state);
        } catch (IndexOutOfBoundsException e) {
            Log.e("probe", "meet a IOOBE in RecyclerView");
        }
    }
}

使用:

RecyclerView recyclerView = (RecyclerView)findViewById(R.id.recycler_view);

recyclerView.setLayoutManager(new WrapContentLinearLayoutManager(activity, LinearLayoutManager.HORIZONTAL, false));

补充:但是这里要注意的是,禁止 RecycleView “下拉刷新” 和 “加载更多” 同时执行 。否则会报:

java.lang.IllegalStateException: Added View has RecyclerView as parent but view is not a real child. Unfiltered index:0
    at android.support.v7.widget.RecyclerView$LayoutManager.addViewInt(RecyclerView.java:7048)
    at android.support.v7.widget.RecyclerView$LayoutManager.addView(RecyclerView.java:7012)
    at android.support.v7.widget.RecyclerView$LayoutManager.addView(RecyclerView.java:7000)
    at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1428)
    at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1377)
    at android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:578)
    at com.jingzhao.shopping.customview.WrapContentLinearLayoutManager.onLayoutChildren(WrapContentLinearLayoutManager.java:27)<---这里
    at android.support.v7.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:3260)
    at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:3069)
    at android.support.v7.widget.RecyclerView.onLayout(RecyclerView.java:3518)
    at android.view.View.layout(View.java:15697)
    at android.view.ViewGroup.layout(ViewGroup.java:5050)
    at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1077)
    at android.view.View.layout(View.java:15697)
    at android.view.ViewGroup.layout(ViewGroup.java:5050)
    at android.support.v4.widget.SwipeRefreshLayout.onLayout(SwipeRefreshLayout.java:598)
    at android.view.View.layout(View.java:15697)
    at android.view.ViewGroup.layout(ViewGroup.java:5050)
    at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1703)
    at android.widget.LinearLayout.layoutHorizontal(LinearLayout.java:1692)
    at android.widget.LinearLayout.onLayout(LinearLayout.java:1468)
    at android.view.View.layout(View.java:15697)
    at android.view.ViewGroup.layout(ViewGroup.java:5050)
    at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1077)
    at android.view.View.layout(View.java:15697)
    at android.view.ViewGroup.layout(ViewGroup.java:5050)
    at android.widget.FrameLayout.layoutChildren(FrameLayout.java:579)
    at android.widget.FrameLayout.onLayout(FrameLayout.java:514)
    at android.view.View.layout(View.java:15697)
    at android.view.ViewGroup.layout(ViewGroup.java:5050)
    at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1703)
    at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1557)
    at android.widget.LinearLayout.onLayout(LinearLayout.java:1466)
    at android.view.View.layout(View.java:15697)
    at android.view.ViewGroup.layout(ViewGroup.java:5050)
    at android.widget.FrameLayout.layoutChildren(FrameLayout.java:579)
    at android.widget.FrameLayout.onLayout(FrameLayout.java:514)
    at android.view.View.layout(View.java:15697)
    at android.view.ViewGroup.layout(ViewGroup.java:5050)
    at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2232)
    at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1984)
    at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1163)
    at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6190)
    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:773)
    at android.view.Choreographer.doCallbacks(Choreographer.java:586)
    at android.view.Choreographer.doFrame(Choreographer.java:556)
    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:759)
    at android.os.Handler.handleCallback(Handler.java:739)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:159)
    at android.app.ActivityThread.main(ActivityThread.java:5540)
    at java.lang.reflect.Method.invoke(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:372)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:964)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:759)

可以做类似的处理:

if(swipeRefreshLayout.isRefreshing()){ 
   return;
}

4.华为部分设备不打印Log

部分的华为设备工程模式下log是关闭的

1.如果是华为手机,进入拨号界面输入:*#*#2846579#*#*进入页面设置。

2.如果是华为pad,进入计算器输入:()()2846579()()= 进入页面设置。

5.一些注意点

(1)平时为了给apk瘦身,我们会对图片进行有损或无损的压缩。那我平时有用到的一个有损压缩网站tinypng,但是切记我们的9图不要压缩,不然会有问题。(这里顺便分享一个做9图的在线工具http://inloop.github.io/shadow4android/

(2)Android的透明主题需谨慎使用。

(3)for循环不要把获得数量的代码写在循环当中:for(int i = 0; i <= list.size(); i ++)

(4)ListView的如果其宽度或高度被设置为wrap_content,会有性能等问题。参见:http://stackoverflow.com/questions/4270278/layout-width-of-a-listview

暂时就想起这么多了,码字不易,多多点赞。

版权声明:本文为博主原创文章,未经博主允许不得转载。http://blog.csdn.net/qq_17766199 举报

相关文章推荐

Android7.0系统,5.0系统,以及5.0以下系统选择本地图片路径转换问题

使用Fileprovider之前需要在mainfest文件中配置配置如下: <provider android:name="android.support.v4.content.FilePro...

GreenDao的简单使用说明(四)特殊的单表1:n

我们在做系统的时候,有时间会遇到单表自循环的情况,最常见的就是省市信息表,它们通过parentid来确定父子关系,这就是一种比较特殊的1:n的关系,我们来看一下,在GreenDao中是如何实现的。 ...

我是如何成为一名python大咖的?

人生苦短,都说必须python,那么我分享下我是如何从小白成为Python资深开发者的吧。2014年我大学刚毕业..

GreenDao的简单使用说明(三)多表的操作1:n

我们在使用数据库的时候,大多数都会是多表联合操作,不会只有一个表的,下面我们就来说一下,多表的操作,这里先拿1:n来说。这是我们平时在设计数据库时最常用的模式。下面我来看一下,GreenDao对1:n...

android 应用退到后台,类似最小化moveTaskToBack(),判断是否是task的根isTaskRoot()

http://blog.csdn.net/wlwl0071986/article/details/48542923 moveTaskToBack()方法:在activity中调用  参...
  • Rodulf
  • Rodulf
  • 2016-04-08 16:46
  • 1281

关于Android app首次安装完成后在安装界面直接“打开”应用再按home键返回桌面,重新进入app重复实例化launcher activity的问题的解决

如标题所述,最近被重复实例化launcher activity这个问题搞得很惨,这个问题有哪些表现呢?如下: 1. 在package installers 安装界面安装完一个应用后,直接打开app...

安卓按home键之后,再次点击程序图标避免再次重新启动程序解决办法

正在运行的android程序,按home键之后退回到桌面,在次点击程序图标避免再次重新启动程序解决办法   例如:一个android程序包含两个Activity,分别为MainActivity和O...
  • 99guo
  • 99guo
  • 2014-01-17 16:33
  • 19803

Activity之isTaskRoot和moveTaskToBack方法简介

1、public boolean isTaskRoot()用来判断该Activity是否为任务栈中的根Activity,即启动应用的第一个Activity 2、public boolean move...

GreenDao的简单使用说明(五)多表n:m

在设计一些比较复杂的数据库结构的时候,我们会遇到表之间是n:m的关系,就是常说的多对多的关系,最常用的情况,就是用户权限这块,日常最常见的就是学生与老师的关系了,哪么我们来看一下GreenDao中如何...

Ubuntu的启动配置文件grub.cfg(menu.lst)设置指南

ubuntu版本9.04,那时候启动配置文件还是menu.lst,到了ubuntu9.10的时候就更名为grub.cfg了,ubuntu 10.04依旧沿用的是grub.cfg,但是这个文件的内容变更...

GreenDao的简单使用说明(六)补遗

通过上面四篇文章,我们已经可以很好的使用的 GreenDao了。这里我再做一些补漏的事,就是我们一直在提,为已存在的表添加字段什么的,但是一直没有实现做过。这里我们就用两种方法,来实现它。     ...
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)