记录面试中的一道大意的题

链接:https://www.nowcoder.com/questionTerminal/ee6c0d0f043246bdb49d0b58d3aa7d15
来源:牛客网
 

阅读代码回答运行结果

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

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);

   }

}

A:Resources$NotFoundException

B:ViewRootImpl$CalledFromWrongThreadException

C:NullPointerException

D:运行正常,mTextViewUser组件上显示内容为10

代码实测:

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。

猜你喜欢

转载自blog.csdn.net/qijingwang/article/details/82670988
今日推荐