Android开发中遇到的bug(2)

1 StackOverflowError

java.lang.StackOverflowError
        at android.os.Looper.myLooper(Looper.java:162)
        at android.app.Dialog.dismiss(Dialog.java:321)
        at com.wql.downloader.fragment.DownloadSelectDialog.dismissDialog(DownloadSelectDialog.java:136)
        at android.app.Dialog.dismiss(Dialog.java:322)
        at com.wql.downloader.fragment.DownloadSelectDialog.dismissDialog(DownloadSelectDialog.java:136)
        at android.app.Dialog.dismiss(Dialog.java:322)
        at com.wql.downloader.fragment.DownloadSelectDialog.dismissDialog(DownloadSelectDialog.java:136)
        at android.app.Dialog.dismiss(Dialog.java:322)
        at com.wql.downloader.fragment.DownloadSelectDialog.dismissDialog(DownloadSelectDialog.java:136)
        at android.app.Dialog.dismiss(Dialog.java:322)
        at com.wql.downloader.fragment.DownloadSelectDialog.dismissDialog(DownloadSelectDialog.java:136)
        at android.app.Dialog.dismiss(Dialog.java:322)
        at com.wql.downloader.fragment.DownloadSelectDialog.dismissDialog(DownloadSelectDialog.java:136)
        at android.app.Dialog.dismiss(Dialog.java:322)
        at com.wql.downloader.fragment.DownloadSelectDialog.dismissDialog(DownloadSelectDialog.java:136)
        at android.app.Dialog.dismiss(Dialog.java:322)
        at com.wql.downloader.fragment.DownloadSelectDialog.dismissDialog(DownloadSelectDialog.java:136)
        at android.app.Dialog.dismiss(Dialog.java:322)
        at com.wql.downloader.fragment.DownloadSelectDialog.dismissDialog(DownloadSelectDialog.java:136)
        at android.app.Dialog.dismiss(Dialog.java:322)
        at com.wql.downloader.fragment.DownloadSelectDialog.dismissDialog(DownloadSelectDialog.java:136)
        at android.app.Dialog.dismiss(Dialog.java:322)
        at com.wql.downloader.fragment.DownloadSelectDialog.dismissDialog(DownloadSelectDialog.java:136)
        at android.app.Dialog.dismiss(Dialog.java:322)
        at com.wql.downloader.fragment.DownloadSelectDialog.dismissDialog(DownloadSelectDialog.java:136)
        at android.app.Dialog.dismiss(Dialog.java:322)
        at com.wql.downloader.fragment.DownloadSelectDialog.dismissDialog(DownloadSelectDialog.java:136)
        at android.app.Dialog.dismiss(Dialog.java:322)
        at com.wql.downloader.fragment.DownloadSelectDialog.dismissDialog(DownloadSelectDialog.java:136)
        at android.app.Dialog.dismiss(Dialog.java:322)
        at com.wql.downloader.fragment.DownloadSelectDialog.dismissDialog(DownloadSelectDialog.java:136)
        at android.app.Dialog.dismiss(Dialog.java:322)
        at com.wql.downloader.fragment.DownloadSelectDialog.dismissDialog(DownloadSelectDialog.java:136)
        at android.app.Dialog.dismiss(Dialog.java:322)
        at com.wql.downloader.fragment.DownloadSelectDialog.dismissDialog(DownloadSelectDialog.java:136)
        at android.app.Dialog.dismiss(Dialog.java:322)
        at com.wql.downloader.fragment.DownloadSelectDialog.dismissDialog(DownloadSelectDialog.java:136)
        at android.app.Dialog.dismiss(Dialog.java:322)
        at com.wql.downloader.fragment.DownloadSelectDialog.dismissDialog(DownloadSelectDialog.java:136)
        at android.app.Dialog.dismiss(Dialog.java:322)
        at com.wql.downloader.fragment.DownloadSelectDialog.dismissDialog(DownloadSelectDialog.java:136)
        at android.app.Dialog.dismiss(Dialog.java:322)
        at com.wql.downloader.fragment.DownloadSelectDialog.dismissDialog(DownloadSelectDialog.java:136)
        at android.app.Dialog.dismiss(Dialog.java:322)
        at com.wql.downloader.fragment.DownloadSelectDialog.dismissDialog(DownloadSelectDialog.java:136)
        at android.app.Dialog.dismiss(Dialog.java:322)
        at com.wql.downloader.fragment.DownloadSelectDialog.dismissDialog(DownloadSelectDialog.java:136)
        at android.app.Dialog.dismiss(Dialog.java:322)
        at com.wql.downloader.fragment.DownloadSelectDialog.dismissDialog(DownloadSelectDialog.java:136)
        at android.app.Dialog.dismiss(Dialog.java:322)
        at com.wql.downloader.fragment.DownloadSelectDialog.dismissDialog(DownloadSelectDialog.java:136)
        at android.app.Dialog.dismiss(Dialog.java:322)
        at com.wql.downloader.fragment.DownloadSelectDialog.dismissDialog(DownloadSelectDialog.java:136)
        at android.app.Dialog.dismiss(Dialog.java:322)
    	at com.wql.downloader.fragment.DownloadSelectDialog.dismissDialog(Downlo

时间:2019年1月23日17:34:21
原因分析:在 Meizu M3 手机上出现的问题。自己程序中的 dismissDialog 方法被不停的调用,导致 StackOverflowError。查看程序会调用这个方法的地方,并打印日志,发现被不是我写的代码调用的。
解决办法:怀疑是方法名在Meizu的系统里也有使用,导致被重复调用。所以,修改方法名 dismissDialog
dismissSelectDialog,重新测试,没有报错了。

2 List.addAll()List.clone() 得到的集合,修改原集合,新集合也会受影响

时间:2019年1月25日11:07:58
这是因为这两种方法获取的集合只是浅拷贝,并不是完全复制出来的。原集合的改动,会马上反映到新的集合上。采用深度拷贝,修改新集合,不会影响到原集合。

3 Room 升级错误

 io.reactivex.exceptions.OnErrorNotImplementedException: The exception was not handled due to missing onError handler in the subscribe() method call. Further reading: https://github.com/ReactiveX/RxJava/wiki/Error-Handling | Migration didn't properly handle VideoInfo(com.wql.downloader.beans.VideoInfo).
     Expected:
    TableInfo{name='VideoInfo', columns={file_path=Column{name='file_path', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0}, status=Column{name='status', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0}, size=Column{name='size', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0}, progress=Column{name='progress', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0}, id=Column{name='id', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=1}, stop_by_network=Column{name='stop_by_network', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0}, name=Column{name='name', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0}, video_url=Column{name='video_url', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0}, duration=Column{name='duration', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0}, page_url=Column{name='page_url', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0}}, foreignKeys=[], indices=[]}
     Found:
    TableInfo{name='VideoInfo', columns={file_path=Column{name='file_path', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0}, status=Column{name='status', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0}, size=Column{name='size', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0}, progress=Column{name='progress', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0}, id=Column{name='id', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=1}, stop_by_network=Column{name='stop_by_network', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=0}, name=Column{name='name', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0}, video_url=Column{name='video_url', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0}, duration=Column{name='duration', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0}, page_url=Column{name='page_url', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0}}, foreignKeys=[], indices=[]}
        at io.reactivex.internal.functions.Functions$OnErrorMissingConsumer.accept(Functions.java:704)
        at io.reactivex.internal.functions.Functions$OnErrorMissingConsumer.accept(Functions.java:701)
        at io.reactivex.internal.observers.LambdaObserver.onError(LambdaObserver.java:77)
        at io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.checkTerminated(ObservableObserveOn.java:281)
        at io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.drainNormal(ObservableObserveOn.java:172)
        at io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.run(ObservableObserveOn.java:255)
        at io.reactivex.android.schedulers.HandlerScheduler$ScheduledRunnable.run(HandlerScheduler.java:119)
        at android.os.Handler.handleCallback(Handler.java:743)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        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.IllegalStateException: Migration didn't properly handle VideoInfo(com.wql.downloader.beans.VideoInfo).
     Expected:
    TableInfo{name='VideoInfo', columns={file_path=Column{name='file_path', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0}, status=Column{name='status', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0}, size=Column{name='size', type='INTEGER', 

时间:2019年1月25日10:13:00
原因分析:在数据库表中增加了一列,升级数据库时报错。增加的字段是 stop_by_network,这个字段的notNull,Room 要求是 true,实际上却是 false,导致升级数据库失败(关于如何快速定位到表的差异,可以查看快速发现 Room 升级失败时表单错误的工具)。
解决办法:修改原来的修改表语句:

database.execSQL("ALTER TABLE videoinfo "
                    + " ADD COLUMN stop_by_network INTEGER");

database.execSQL("ALTER TABLE videoinfo "
                    + " ADD COLUMN stop_by_network INTEGER NOT NULL DEFAULT 0");

明确声明这列的notNull为true。在这里我也指定了默认值是0,这是具体的业务需求。

4 AS安装apk时报错: INSTALL_FAILED_INVALID_APK

Installation failed with message Failed to finalize session : INSTALL_FAILED_INVALID_APK: /data/app/vmdl344396929.tmp/1_slice__ version code 18 inconsistent with 19.
It is possible that this issue is resolved by uninstalling an existing version of the apk if it is present, and then re-installing.

WARNING: Uninstalling will remove the application data!

Do you want to uninstall the existing application?

时间:2019年1月25日11:58:47
解决办法:Rebuild Project

5 MalformedURLException

01-25 21:19:15.640 1400-1400/com.wql.downloaderplay E/EventLogger: playerFailed [3.03]
    com.google.android.exoplayer2.ExoPlaybackException: com.google.android.exoplayer2.upstream.HttpDataSource$HttpDataSourceException: Unable to connect to /storage/emulated/0/AwesomeDownLoader/Roles That Jake Gyllenhaal Turned Down from Spider-Man: Far From Home (2019)_1548421596.mp4
        at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:354)
        at android.os.Handler.dispatchMessage(Handler.java:98)
        at android.os.Looper.loop(Looper.java:150)
        at android.os.HandlerThread.run(HandlerThread.java:61)
     Caused by: com.google.android.exoplayer2.upstream.HttpDataSource$HttpDataSourceException: Unable to connect to /storage/emulated/0/AwesomeDownLoader/Roles That Jake Gyllenhaal Turned Down from Spider-Man: Far From Home (2019)_1548421596.mp4
        at com.google.android.exoplayer2.upstream.DefaultHttpDataSource.open(DefaultHttpDataSource.java:281)
        at com.google.android.exoplayer2.upstream.DefaultDataSource.open(DefaultDataSource.java:250)
        at com.google.android.exoplayer2.upstream.StatsDataSource.open(StatsDataSource.java:83)
        at com.google.android.exoplayer2.source.ExtractorMediaPeriod$ExtractingLoadable.load(ExtractorMediaPeriod.java:885)
        at com.google.android.exoplayer2.upstream.Loader$LoadTask.run(Loader.java:381)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
        at java.lang.Thread.run(Thread.java:833)
     Caused by: java.net.MalformedURLException: Protocol not found: /storage/emulated/0/AwesomeDownLoader/Roles That Jake Gyllenhaal Turned Down from Spider-Man: Far From Home (2019)_1548421596.mp4
        at java.net.URL.<init>(URL.java:176)
        at java.net.URL.<init>(URL.java:125)
        at com.google.android.exoplayer2.upstream.DefaultHttpDataSource.makeConnection(DefaultHttpDataSource.java:426)
        at com.google.android.exoplayer2.upstream.DefaultHttpDataSource.open(DefaultHttpDataSource.java:279)
        at com.google.android.exoplayer2.upstream.DefaultDataSource.open(DefaultDataSource.java:250) 
        at com.google.android.exoplayer2.upstream.StatsDataSource.open(StatsDataSource.java:83) 
        at com.google.android.exoplayer2.source.ExtractorMediaPeriod$ExtractingLoadable.load(ExtractorMediaPeriod.java:885) 
        at com.google.android.exoplayer2.upstream.Loader$LoadTask.run(Loader.java:381) 
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113) 
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588) 
        at java.lang.Thread.run(Thread.java:833) 

暂未解决。

6 onScrollChangedWebView 里的方法吗?

不是,是 View 里的方法,在API1就添加的。

7 ExoPlayer 不支持 .avi 格式

查看官方文档,确实不在支持了。
解决办法是:在播放错误回调里,使用系统的 MediaPlayer 来播放。

8 Decompiled .class file bytecode version 52.0(java 8)

查看 WebViewClient 这个类的源码:
点击右侧的 Open source file,却看不到里面的源码:

查看我编译的版本 28,已经下载过了:
在这里插入图片描述
时间:2019年1月28日11:25:01
解决办法:点击上图中的 Edit,进入向导页面,在这里会更新当前sdk的位置或者安装一个新的版本:

点击 Next,进入:

更新后就好了。

9 java.lang.RuntimeException: setDataSource failed: status = 0x80000000

 E/AndroidRuntime: FATAL EXCEPTION: pool-13-thread-1
    java.lang.RuntimeException: setDataSource failed: status = 0x80000000
        at android.media.MediaMetadataRetriever.setDataSource(Native Method)
        at android.media.MediaMetadataRetriever.setDataSource(MediaMetadataRetriever.java:69)
        at android.media.MediaMetadataRetriever.setDataSource(MediaMetadataRetriever.java:157)
        at com.wql.downloader.utils.DownloadManager.getDuration(DownloadManager.java:243)
        at com.wql.downloader.utils.DownloadManager.access$500(DownloadManager.java:35)
        at com.wql.downloader.utils.DownloadManager$3.run(DownloadManager.java:219)
        at com.wql.downloader.utils.ThreadPool$TaskWithPriority.run(ThreadPool.java:166)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
        at java.lang.Thread.run(Thread.java:764)

时间:2019年1月28日20:02:18
问题代码:

/**
     * 获取视频的时长
     * Note:这是一个耗时操作,放在子线程中
     *
     * @param filePath 文件路径
     * @return long duration
     */
    private long getDuration(String filePath) {
           	MediaMetadataRetriever retriever = new MediaMetadataRetriever();
            retriever.setDataSource(MyApplication.getContext(), Uri.fromFile(new File(filePath)));
            String durationStr = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
            retriever.release();
            return Long.parseLong(durationStr);
    }

在网上查询没有找到原因,只在一个htc的手机上出现这种情况。暂时捕获异常处理。

10 notifyItemRemoved 不起作用

时间:2019年1月30日20:26:35
原因分析:

 boolean remove = mData.remove(info);
 mView.notifyItemRemoved(positon, mData.size());

上面代码中的 info 并不是 mData 的元素,导致删除返回 false;然后,下面调用刷新删除条目时失败。但为什么 info 不是 mData 的元素呢?是因为之前调用了下面的代码更新条目:

@Override
public void notifyItemChanged(int position, VideoInfo info) {
    RecyclerView.ViewHolder viewHolder = mRecyclerView.findViewHolderForAdapterPosition(position);
    if (viewHolder instanceof DownloadProgressAdapter.DownloadProgressViewHolder) {
        DownloadProgressAdapter.DownloadProgressViewHolder itemHolder
                = (DownloadProgressAdapter.DownloadProgressViewHolder) viewHolder;
        itemHolder.bindItem(info, position);
    }
}

上面方法的 info 对象是深度拷贝后的 VideoInfo 对象,它和原来的对象内容是一样的,但是地址是不一样的。
在上面的方法中,通过 mRecyclerView.findViewHolderForAdapterPosition(position) 获取对应位置的 ViewHolder,这一步是正确的。然后进入到 if 语句里,ViewHolderbindItem 方法,绑定了拷贝后的 VideoInfo 对象。
所以,解决办法是在调用 notifyItemChanged 方法时,使用原来数据集合里的 VideoInfo 对象。

发布了78 篇原创文章 · 获赞 46 · 访问量 7万+

猜你喜欢

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