Android学习之分析代码&巩固基础

最近为了准备面试去刷题,今天遇到了一个非常典型的,觉得很经典的一个题目:

阅读代码回答运行结果:

public classMainActivity extends Activity implements OnClickListener
{
   private Button mBtnLogin = (Button) findViewById(R.id.btn_login);
   private TextView mTextViewUser;
  
   @Override
   protected void onCreate(BundlesavedInstanceState)
   {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mTextViewUser = (TextView) findViewById(R.id.textview_user);
        mBtnLogin.setOnClickListener(this);
        new Thread()
        {
            @Override
            public void run()
            {
                mTextViewUser.setText(10);
            }
        }.start();
   }
  
   @Override
   public void onClick(View v)
   {
        mTextViewUser.setText(20);
   }
}
猛的一看没有什么错误,但其实是很多细节没有注意到,所以当时这个题目做错了,看了一个大神的详解之后,受益颇多:

1、首先会报错NullPointerException,就是privateButton mBtnLogin = (Button) findViewById(R.id.btn_login);这个位置,要先加载了layout后才能成功获取到相应的按钮组件对象
2、修改NullPointerException错误后再运行,报错 Resources$NotFoundException,在mTextViewUser.setText(10);这个位置(原本以为会先检查onclick方法里的setText(),但实际是run()里的setText()),要改成字符串形式;
3、修改上面的错误后再运行,报错Resources$NotFoundException,这次就轮到mTextViewUser.setText(20);这个位置了;
4、修改上面的错误后再运行,没有报错,程序成功运行,点击按钮后TextView由10变为20,说好的不能在非UI线程里更新UI组件呢?翻看别人的博客后,终于找到答案了,其实非UI线程是可以刷新UI的,前提是它要拥有自己的ViewRoot,ViewRoot是在onResume()里addview()创建的,所以是在 onResume()检查是否为UI线程,一般在onCreate()中通过子线程可以更新UI,但官方不建议这样做,因为 Android UI操作并不是线程安全的。
PS:而且,可以试下在上面代码的run()中setText()前加一句Thread.sleep(2000),先让线程休眠个2到3秒,就会报错 ViewRootImpl$CalledFromWrongThreadException,说明已经检查到在非UI线程里更新UI。

其实,实测之后就会发觉这些问题,感觉分析的很不错,题目也很经典,故而记录下来,警示自己要注重细节~!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值