Features
V2EX  ›  Android

刚刚开始学习 Android,请问一下下面这两行代码为什么会导致闪退?

  •  
  •   Features · Nov 24, 2021 · 15795 views
    This topic created in 1806 days ago, the information mentioned may be changed or developed.

    编译通过,但是会闪退


    public View getView(int i, View view, ViewGroup viewGroup) {
            ViewHolder holder;
            if(view == null){
                holder = new ViewHolder();
                mView = LayoutInflater.from(context).inflate(R.layout.grid_item,viewGroup,false);
                holder.img  = (ImageView) mView.findViewById(R.id.icon_item);
                holder.title = (TextView) mView.findViewById(R.id.icon_text);
            }else{
                holder = (ViewHolder) mView.getTag();
            }
    
            //这两行会导致闪退
            holder.img.setImageResource(arr.get(i).getRid());
            holder.title.setText(arr.get(i).getTitle());
    
            Log.e("myapp","abc");
    
            return mView;
        }
    
    Supplement 1  ·  Nov 24, 2021

    这样写就完全OK,应该是view.getTag() 没有正确返回ViewHolder对象

            mView = LayoutInflater.from(context).inflate(R.layout.grid_item,viewGroup,false);
            ImageView img  = (ImageView) mView.findViewById(R.id.icon_item);
            TextView title = (TextView) mView.findViewById(R.id.icon_text);
    
            img.setImageResource(arr.get(i).getRid());
            title.setText(arr.get(i).getTitle());
    
            return mView;
    
    Supplement 2  ·  Nov 24, 2021
    Logcat 报错:
    java.lang.NullPointerException: Attempt to read from field 'android.widget.ImageView cn.mousover.helloworld4.MyGridAdapter$ViewHolder.img' on a null object reference
    Supplement 3  ·  Nov 24, 2021

    前面使用ListView,没有setTag,却能正常跑起来,所以我忽略了setTag这个api

                ViewHolder holder = null;
                if(view == null){
                    holder = new ViewHolder();
                    mView = LayoutInflater.from(context).inflate(R.layout.view_item,viewGroup,false);
                    holder.title =  (TextView) mView.findViewById(R.id.title);
                    holder.desc = (TextView) mView.findViewById(R.id.desc);
                    holder.img = (ImageView) mView.findViewById(R.id.img);
                }else{
                    holder =(ViewHolder)mView.getTag();
                }
    
                holder.title.setText(data.get(i).getTitle());
                holder.desc.setText(data.get(i).getDesc());
                holder.img.setImageResource(data.get(i).getIcon());
    
                return mView;
    
    
    32 replies  •  2021-12-07 14:10:00 +08:00
    hello2090
    hello2090
    Nov 24, 2021
    1
    虽然没做过 android 你这个 debug 一下不就是了
    holder, holder.img 是不是空,arr 或者 arr.get(i) 是不是空
    SupperMary
    SupperMary
    Nov 24, 2021❤️1
    2
    adb shell 上去,logcat -b crash 会告诉你很详细的错误原因
    Features
    Features
    OP
    Nov 24, 2021
    3
    @hello2090 这个确实空指针了,但是不知道什么原因导致的
    集合长度为 4 ,会更新 4 次,但是集合数据是正常的
    hello2090
    hello2090
    Nov 24, 2021❤️1
    4
    @Features 很简单啊,arr 更新的时候打个 log, 运行 holder.img.setImageResource(arr.get(i).getRid()); 之前打个 log 看看呗

    你这个只是读,而且还不是数值不对,而是直接 null, 应该不会是多线程的问题,
    mx8Y3o5w3M70LC4y
    mx8Y3o5w3M70LC4y
    Nov 24, 2021 via Android❤️1
    5
    if 分支结尾需要 mView.setTag(holder)一下吧?现在安卓基本上不用 listview 了,基本上都是 recyclerview 来处理了。可以直接学 recyclerview
    xFrye
    xFrye
    Nov 24, 2021❤️1
    6
    ListView? 有想过通过 getTag 获取到的 holder 是从哪里来的么? viewHolder 不存下来的话,怎么会拿得到呢
    mx8Y3o5w3M70LC4y
    mx8Y3o5w3M70LC4y
    Nov 24, 2021 via Android
    7
    @xFrye 哈哈初学者,可能还不是太明白这个 item 复用吧
    xFrye
    xFrye
    Nov 24, 2021
    8
    @lvdb 应该是的,不过写的时候还是要多思考一下。

    https://juejin.cn/post/6844903911225032712 楼主可以看看这个梳理下,不过现在基本上确实 recyclerview 用的比较多了
    busymilk
    busymilk
    Nov 24, 2021 via iPhone
    9
    你没有 setTag. getTag 当然是空
    xuhaoyangx
    xuhaoyangx
    Nov 24, 2021
    10
    现在就别用 listview 了
    Features
    Features
    OP
    Nov 24, 2021
    11
    @xFrye 是 GridView,ListView 写了就没问题😂
    Features
    Features
    OP
    Nov 24, 2021
    12
    @xuhaoyangx 只是当预热了解
    sankemao
    sankemao
    Nov 24, 2021
    13
    没有 setTag,当然 get 不到,而且下面你的写法,失去了复用机制
    youxiachai
    youxiachai
    Nov 24, 2021
    14
    这代码...不是我 10 年前的写法吗....

    现在用 RV 用不着这样写了啊...
    youxiachai
    youxiachai
    Nov 24, 2021
    15
    不对...按道理,现在基本 RV 一把梭.... lz 用的什么入门资料..怎么还有这么远古的用法
    Features
    Features
    OP
    Nov 24, 2021
    16
    @xFrye 确实是要先 setTag ,但是我之前写了一个 demo ,是 ListView 的,没有 setTag 却可以😭
    Features
    Features
    OP
    Nov 24, 2021
    17
    @lvdb 是的是的,谢谢
    Features
    Features
    OP
    Nov 24, 2021
    18
    @youxiachai 就是菜鸟教程,哈哈,没事,反正先了解下,应该都没问题吧
    Features
    Features
    OP
    Nov 24, 2021
    19
    @sankemao 好奇怪欸,我用 ListView 的时候,不用 setTag 也能跑起来,用 GridView 的时候却报错了
    youxiachai
    youxiachai
    Nov 24, 2021
    20
    @Features 现在有 google 的 codelab 那么好的教程....完全搞不懂现在的年轻人,怎么去看采集网站的教程..
    Features
    Features
    OP
    Nov 24, 2021
    21
    @youxiachai 我是找了个视频,看了视频以后,做完视频的练习
    再自己找一些练习做的,纯看教程我有点吃力,学不动的感觉
    等我学完基础,肯定会去官网做一遍,巩固下
    可能这就是学渣吧😂
    学新知识都要学几回才能掌握
    youxiachai
    youxiachai
    Nov 24, 2021
    22
    @Features google 官方有专门针对新手的视频... 完整的一套最新,没必要看这种过时的资料
    a4390509
    a4390509
    Nov 24, 2021❤️1
    23
    不崩溃是因为数据少,item 没有填充满一个屏幕,所以 view 没有复用,所以逻辑走到了 view==null 的逻辑分支里面。

    崩溃是因为 view 复用了,但是你没有在 view 创建的时候 setTag ,所以在 else 逻辑分支里面获取的时候 getTag 是个空的
    ykrank
    ykrank
    Nov 24, 2021❤️2
    24
    八年老 Android ,从 Android2.0 适配起,建议你不要学客户端了。历史知识太多,真要靠这个吃饭,现在既要精通 Android ,又要精通 JVM ,各种常用的第三方框架源码都得看。最新代码基本都是 kotlin 。google 官方的推荐框架换了一茬又一茬,每次学习都是新架构。但是你要维护的工程完全可能有各种历史代码,不知道历史原因的话看起来就是乱麻。
    当然如果是自己写给自己玩的,那随意了,直接最新架构一把梭,完全不用在乎历史框架。不过这种情况下那也不如 google 新的 flutter ,还可以直接打包成 IOS 和 PC 端。
    windyskr
    windyskr
    Nov 25, 2021 via Android
    25
    @ykrank 真心请教现在学 Flutter 需要啥储备知识,去哪学习比较好?
    caixiangyu17
    caixiangyu17
    Nov 25, 2021❤️1
    26
    现在学安卓直接从 kotlin 和 jetpack compose 入门吧,没有安卓面试会不问你 kotlin coroutine 的,所以别写 java 了
    Features
    Features
    OP
    Nov 25, 2021
    27
    @ykrank 我有 java se 和 ee 基础,所以感觉用 java 轻松点
    kotlin 以后作为拓展再学习吧
    xuhaoyangx
    xuhaoyangx
    Nov 25, 2021
    28
    你真的要学 Android

    直接用最新的谷歌 jetpack 的东西

    Kotlin + Jetpack 一套框架

    Kotlin + jetpack Compose 新的声明式 UI

    flutter 也可以看看,flutter 和 compose 基本是一种思想,会一个另一个基本也差不多了。

    跨平台的可以学,但别以为能解万难,凡是涉及多一点点稍微底层一点的功能、API ,都要你懂原生。

    我现在做 SDK 的,遇到太多来自别的端转移动端,只会 RN Flutter weex Uniapp 等这些,水的不行。
    xuhaoyangx
    xuhaoyangx
    Nov 25, 2021
    29
    @Features 先学 kotlin
    olindays
    olindays
    Nov 25, 2021
    30
    用《第一行代码》第三版,学习 Android 开发的同时也学了 kotlin ,我个人觉得这本书对我这种菜鸟水平的编程爱好者很友好,你不妨试试看。
    stardust21
    stardust21
    Nov 25, 2021
    31
    @ykrank 老哥中肯。
    @Features 列表直接学 RV 吧,看官方文档就行: https://developer.android.google.cn/guide/topics/ui/layout/recyclerview
    kujio
    kujio
    Dec 7, 2021
    32
    你这 holder 写的,holder 不是这么存的,也不是这么取的!
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   1434 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 84ms · UTC 22:45 · PVG 06:45 · LAX 14:45 · JFK 17:45
    ♥ Do have faith in what you're doing.