Android开发中遇到的bug(1)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/willway_wang/article/details/85175542

前言

看到其他同学总结的开发中的bug,真的很受教。自己也应该向他们学习,“好记性不如烂笔头”,何况自己又很健忘。希望自己也能总结出一份不错的bug汇总。

正文

1 No toolchains found in the NDK toolchains folder for ABI with prefix: mipsel-linux-android

日期:2018年12月21日21:52:42
这是在 AS 编译项目时出现的错误,自己是通过搜索解决的。查看: 完美解决 No toolchains found in the NDK toolchains folder for ABI with prefix: mips64el-linux-android

2 Caused by: android.database.sqlite.SQLiteException: no such table: (code 1) Android

这个异常时因为数据库不存在导致的。在我的项目中,是因为assets 目录下的数据库没有解压到data/data/目录下导致的。

3 RecyclerView notifyItemChanged 没有效果

日期:2019年1月9日13:10:32
这是因为自己在子线程中调用此刷新导致的,需要在主线程中调用。

4 NotSerializableException 异常

java.lang.RuntimeException: Parcelable encountered IOException writing serializable object (name = com.wql.downloader.beans.TabInfo)
Caused by: java.io.NotSerializableException: com.wql.downloader.fragment.WebFragment
原因:这是因为在一个实现了 Serializable 接口的类中,存在未序列化的变量。
解决办法:使用 transient 关键字修饰该变量,阻止其被序列化。但最终的解决办法是不在这里保存 WebFragment 对象。

5 RecyclerView 刷新时的异常

01-10 22:08:22.746 26570-26570/com.wql.downloaderplay E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.wql.downloaderplay, PID: 26570
    java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid view holder adapter positionViewHolder{5f6ec69 position=3 id=-1, oldPos=3, pLpos:-1 scrap [attachedScrap] tmpDetached no parent} android.support.v7.widget.RecyclerView{5b499f7 VFED..... .F....ID 0,171-1080,1590 #7f08014a app:id/recycler_view}, adapter:com.wql.downloader.adapters.DownloadProgressAdapter@d90064, layout:android.support.v7.widget.LinearLayoutManager@bdbd2cd, context:com.wql.downloader.activity.HomeActivity@629111a
        at android.support.v7.widget.RecyclerView$Recycler.validateViewHolderForOffsetPosition(RecyclerView.java:5715)
        at android.support.v7.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:5898)
        at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5858)
        at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5854)
        at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2230)
        at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1557)
        at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1517)
        at android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:612)
        at android.support.v7.widget.RecyclerView.dispatchLayoutStep1(RecyclerView.java:3875)
        at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:3639)
        at android.support.v7.widget.RecyclerView.onLayout(RecyclerView.java:4194)
        at android.view.View.layout(View.java:16754)
        at android.view.ViewGroup.layout(ViewGroup.java:5462)
        at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1079)
        at android.view.View.layout(View.java:16754)
        at android.view.ViewGroup.layout(ViewGroup.java:5462)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:338)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:273)
        at android.view.View.layout(View.java:16754)
        at android.view.ViewGroup.layout(ViewGroup.java:5462)
        at android.support.v4.widget.DrawerLayout.onLayout(DrawerLayout.java:1231)
        at android.view.View.layout(View.java:16754)
        at android.view.ViewGroup.layout(ViewGroup.java:5462)
        at android.support.constraint.ConstraintLayout.onLayout(ConstraintLayout.java:1915)
        at android.view.View.layout(View.java:16754)
        at android.view.ViewGroup.layout(ViewGroup.java:5462)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:338)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:273)
        at android.view.View.layout(View.java:16754)
        at android.view.ViewGroup.layout(ViewGroup.java:5462)
        at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1764)
        at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1607)
        at android.widget.LinearLayout.onLayout(LinearLayout.java:1516)
        at android.view.View.layout(View.java:16754)
        at android.view.ViewGroup.layout(ViewGroup.java:5462)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:338)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:273)
        at android.view.View.layout(View.java:16754)
        at android.view.ViewGroup.layout(ViewGroup.java:5462)
        at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1764)
        at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1607)
        at android.widget.LinearLayout.onLayout(LinearLayout.java:1516)
        at android.view.View.layout(View.java:16754)
        at android.view.ViewGroup.layout(ViewGroup.java:5462)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:338)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:273)
        at com.android.internal.policy.PhoneWindow$DecorView.onLayout(PhoneWindow.java:2748)
        at android.view.View.layout(View.java:16754)
        at android.view.ViewGroup.layout(ViewGroup.java:5462)
        at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2225)
        at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1982)
    	at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:

待解决。

6 关于Activity切换动画(overridePendingTransition)的黑色背景问题

这是因为在 overridePendingTransition:

public void overridePendingTransition(int enterAnim, int exitAnim)

的第二个参数设置为 null。
解决办法是在第二个参数设置动画,但不会有任何的动画。

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
           android:fromXDelta="0"
           android:toXDelta="0"
           android:fromYDelta="0"
           android:toYDelta="0"
           android:duration="250"/>

7 android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?

时间:2019年1月16日13:20:51
使用非Activity的上下文startActivity 时,需要:

chooser.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

8 分享文件时报错 FileUriExposedException:

android.os.FileUriExposedException: file:///storage/emulated/0/AwesomeDownload/Download/IMDb%20-%20Movies%2C%20TV%20and%20Celebrities%20-%20IMDb_1547706246.mp4 exposed beyond app through ClipData.Item.getUri()

时间:2019年1月17日17:07:12
这是在7.0以上手机上的报错,7.0开始不允许带有file://的Uri离开应用,要和其他应用共享File数据,需要使用content://的方式。
解决办法:适配7.0以上的手机。

public static boolean shareFile(Context context, File file) {
        if (file == null || !file.exists()) {
            Toast.makeText(MyApplication.getContext(), R.string.finish_popup_menu_share_no_file, Toast.LENGTH_SHORT).show();
            return false;
        }
        Intent share = new Intent(Intent.ACTION_SEND);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            Uri uri = FileProvider.getUriForFile(context,
                    context.getApplicationContext().getPackageName() + ".fileprovider", file);
            share.putExtra(Intent.EXTRA_STREAM, uri);
        } else {
            share.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(file));
        }
        share.setType(getMimeType(file.getAbsolutePath()));
        //  If you're using an intent to make the system open your file, you may need to add the following line of code
        share.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        if (context.getPackageManager().resolveActivity(share, PackageManager.MATCH_DEFAULT_ONLY) != null) {
            try {
                Intent chooser = Intent.createChooser(share, context.getString(R.string.finish_popup_menu_share));
                chooser.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                context.startActivity(chooser);
                return true;
            } catch (ActivityNotFoundException e) {
                return false;
            }
        }

        return false;
    }

在 xml 目录下,添加 storage_file_paths.xml:

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="external_files" path="."/>
</paths>

在清单文件中添加:

<provider
    android:name="android.support.v4.content.FileProvider"
    android:authorities="${applicationId}.fileprovider"
    android:exported="false"
    android:grantUriPermissions="true">
    <!--grantUriPermissions:true,表示授予 URI 临时访问权限。-->
    <!--exported:要求必须为false,为true则会报安全异常。-->
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/storage_file_paths" />
</provider>

9 在 API19的手机上使用 vector 资源报错

android.content.res.Resources$NotFoundException: File res/drawable/ic_book_24dp.xml from drawable resource ID #0x7f080080. If the resource you are trying to use is a vector resource, you may be referencing it in an unsupported way. See AppCompatDelegate.setCompatVectorFromResourcesEnabled() for more info.
        at android.content.res.Resources.loadDrawable(Resources.java:2152)
        at android.content.res.Resources.getDrawable(Resources.java:710)
        at com.wql.downloader.fragment.MyFragment.initView(MyFragment.java:72)
        at com.wql.downloader.fragment.MyFragment.onViewCreated(MyFragment.java:59)
        at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1471)
        at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1784)
        at android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:797)
        at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2625)
        at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2411)
        at android.support.v4.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2366)
        at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2273)
        at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:733)
        at android.os.Handler.handleCallback(Handler.java:808)
        at android.os.Handler.dispatchMessage(Handler.java:103)
        at android.os.Looper.loop(Looper.java:193)
        at android.app.ActivityThread.main(ActivityThread.java:5299)
        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:825)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:641)
        at dalvik.system.NativeStart.main(Native Method)
     Caused by: org.xmlpull.v1.XmlPullParserException: Binary XML file line #1: invalid drawable tag vector
        at android.graphics.drawable.Drawable.createFromXmlInner(Drawable.java:933)
        at android.graphics.drawable.Drawable.createFromXml(Drawable.java:877)
        at android.content.res.Resources.loadDrawable(Resources.java:2148)
        at android.content.res.Resources.getDrawable(Resources.java:710) 
        at com.wql.downloader.fragment.MyFragment.initView(MyFragment.java:72) 
        at com.wql.downloader.fragment.MyFragment.onViewCreated(MyFragment.java:59) 
        at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1471) 
        at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1784) 
        at android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:797) 
        at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2625) 
        at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2411) 
        at android.support.v4.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2366) 
        at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2273) 
        at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:733) 
        at android.os.Handler.handleCallback(Handler.java:808) 
        at android.os.Handler.dispatchMessage(Handler.java:103) 
        at android.os.Looper.loop(Looper.java:193) 
        at android.app.ActivityThread.main(ActivityThread.java:5299) 
        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:825) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:641) 
        at dalvik.system.NativeStart.main(Native Method) 

时间:2019年1月19日11:02:31
解决办法:在Activity的基类中添加:

static {
        AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}

参考:https://stackoverflow.com/questions/38467680/android-getting-resourcesnotfoundexception-for-abc-ic-ab-back-material

10 混淆反射导致的异常

01-22 09:48:05.434 8410-8410/? E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.wql.downloaderplay, PID: 8410
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.wql.downloaderplay/com.wql.downloader.activity.HomeActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Class java.lang.Object.getClass()' on a null object reference
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2444)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2504)
        at android.app.ActivityThread.access$900(ActivityThread.java:165)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1368)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:150)
        at android.app.ActivityThread.main(ActivityThread.java:5546)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:794)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:684)
     Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Class java.lang.Object.getClass()' on a null object reference
        at com.wql.downloader.views.BottomNavigationViewEx.getBottomNavigationItemViews(BottomNavigationViewEx.java:46)
        at com.wql.downloader.views.BottomNavigationViewEx.b(BottomNavigationViewEx.java:35)
        at com.wql.downloader.activity.HomeActivity.e(HomeActivity.java:746)
        at com.wql.downloader.activity.HomeActivity.r(HomeActivity.java:163)
        at com.wql.downloader.activity.HomeActivity.onCreate(HomeActivity.java:136)
        at android.app.Activity.performCreate(Activity.java:6367)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1110)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2397)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2504) 
        at android.app.ActivityThread.access$900(ActivityThread.java:165) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1368) 
        at android.os.Handler.dispatchMessage(Handler.java:102) 
        at android.os.Looper.loop(Looper.java:150) 
        at android.app.ActivityThread.main(ActivityThread.java:5546) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:794) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:684) 

时间:2019年1月22日22:38:20
原因:使用 BottomNavigationView 进行扩展,得到如下类:

public class BottomNavigationViewEx extends BottomNavigationView {

    public BottomNavigationViewEx(Context context) {
        super(context);
    }

    public BottomNavigationViewEx(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public BottomNavigationViewEx(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    private BottomNavigationItemView[] mButtons;
    private BottomNavigationMenuView mMenuView;

    public BottomNavigationItemView getBottomNavigationItemView(int position) {
        return getBottomNavigationItemViews()[position];
    }

    private BottomNavigationItemView[] getBottomNavigationItemViews() {
        if (null != mButtons)
            return mButtons;
        /*
         * 1 private final BottomNavigationMenuView mMenuView;
         * 2 private BottomNavigationItemView[] mButtons;
         */
        BottomNavigationMenuView mMenuView = getBottomNavigationMenuView();
        mButtons = getField(mMenuView.getClass(), mMenuView, "buttons");
        return mButtons;
    }

    /**
     * get private mMenuView
     *
     * @return
     */
    private BottomNavigationMenuView getBottomNavigationMenuView() {
        if (null == mMenuView)
            mMenuView = getField(BottomNavigationView.class, this, "menuView");
        return mMenuView;
    }

    /**
     * get private filed in this specific object
     *
     * @param targetClass
     * @param instance    the filed owner
     * @param fieldName
     * @param <T>
     * @return field if success, null otherwise.
     */
    private <T> T getField(Class targetClass, Object instance, String fieldName) {
        try {
            Field field = targetClass.getDeclaredField(fieldName);
            field.setAccessible(true);
            return (T) field.get(instance);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return null;
    }
}

但是在打 release 包时,没有添加混淆文件,导致其中需要取反射的字段 buttons,menuView,无法找到。最终导致空指针。
添加混淆文件,解决了这个问题:

-keep public class android.support.design.widget.BottomNavigationView { *; }
-keep public class android.support.design.internal.BottomNavigationMenuView { *; }
-keep public class android.support.design.internal.BottomNavigationItemView { *; }

猜你喜欢

转载自blog.csdn.net/willway_wang/article/details/85175542